Mountain Lion にアップグレードしたら NetBeans 7.1 を起動できなくなりました
というわけで Dock アイコンから起動できなくなってしまったので起動コマンドを直接叩いてみました。
すると・・・
$ /Applications/NetBeans/NetBeans\ 7.1.app/Contents/Resources/NetBeans/bin/netbeans Cannot find java. Please use the --jdkhome switch.
Java が見つけられていないようです。
この Mac には Lion の時から Java7 がインストールされていて Mountain Lion にアップグレードした後もちゃんと参照はできるようです。
$ which java /usr/bin/java $ java -version java version "1.7.0_05" Java(TM) SE Runtime Environment (build 1.7.0_05-b05) Java HotSpot(TM) 64-Bit Server VM (build 23.1-b03, mixed mode)
アップグレードによってどこの参照が途切れてしまったのかわからないですがとにかく起動スクリプト内で java が参照できなくなってしまったようなので、設定ファイルに直接 Java Home を指定することにしました。
/Applications/NetBeans/NetBeans 7.1.app/Contents/Resources/NetBeans/etc/netbeans.conf
... #netbeans_jdkhome="/path/to/jdk" netbeans_jdkhome="/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home"
上記の netbeans_jdkhome="/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home"
が追記した部分です。
これで、無事 Dock からもNetBeans を起動できるようになりました。
TUN/TAPドライバ - パフォーマンス改善までのデバッグ履歴
私はここ数年 Solaris 向けの TUN/TAP ドライバの保守をしているのですが、最近OpenVPNのフォーラムに以下のような書き込みがあるのを見つけました。
http://forums.openvpn.net/topic9542.html
In some sources it was implied that while some performance degradation may be due to OpenSSL operating on small packets, or TCP/UDP flow control mismatches, or MTU and fragmentations, much of the rest can be blamed on the TUN/TAP interface software - which is made differently for different OSes, often by different authors, and performs - well - differently.
投稿した方は Solaris での OpenVPN のパフォーマンスをが出ない事に困っており、TUN/TAPドライバの実装に問題があるのでは無いかと疑って居るようです。実際の投稿の意図としては TUN/TAP ドライバ自体のパフォーマンスの改善では無く、Solaris バンドルの tunnel ドライバを TUN/TAP ドライバの代わりに使えないか?というものでしたが「パフォーマンスが酷く悪い」というのがちょっと気になり調べて見ることにしました。
結論的には調査の結果 Solaris 向け TUN/TAP ドライバにパフォーマンスのボトルネックが見つかり、コードを変更することにより劇的にパフォーマンスを改善できたのですが、そこにいたるまでかなりの道程があったので、後々の備忘録の意味も含めてデバッグ履歴を書き留めておきます。
現在のパフォーマンス測定
パフォーマンスが悪い、といっても遅さの指針となるデータがないと目標も立てられませんし、改善の評価も行えません。
そこで、今回はネットワークパフォーマンス測定ツール netperf を使ってパフォーマンスを測定することにしました。
環境
結果
実ネットワークでの転送速度 | 1 Gbps |
OpenVPN+TAP ドライバ経由での転送 | 20 Mbps |
実際の出力
実ネットワーク
sol11 $ netperf -H oi148 MIGRATED TCP STREAM TEST from ::ffff:0.0.0.0 (0.0.0.0) port 0 AF_INET to oi148 (192.168.1.3) port 0 AF_INET Recv Send Send Socket Socket Message Elapsed Size Size Size Time Throughput bytes bytes bytes secs. 10^6bits/sec 128000 49152 49152 10.00 1028.79
OpenVPN+TAP 経由
sol11 $ netperf -H 192.168.30.1 MIGRATED TCP STREAM TEST from ::ffff:0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.30.1 (192.168.30.1) port 0 AF_INET Recv Send Send Socket Socket Message Elapsed Size Size Size Time Throughput bytes bytes bytes secs. 10^6bits/sec 128000 49152 49152 10.32 22.88
なんと実ネットワークと OpenVPN+TAP による仮想ネットワークで46倍ものスループットの差があります。
もちろんソフトウェア的に余計な処理かかなり入っているのである程度がオーバーヘッドがでるのはしょうがないですが、これはあまりにも差が開きすぎています。
というわけで、現状把握とともに目標を
『実ネットワークの10分の1以上(100Mbps以上)まで改善する』
こととしました。
Dtraceによる測定
せっかくSolarisには dtrace(1M) というトレーサーがついているのですから、まずは Dtrace でボトルネック箇所を探してみます。
TAPドライバのトレース。
まずはドライバのボトルネック調査をしてみます。
- TAPドライバ内の関数の呼び出し回数
count_tuntap.d
fbt:tap::entry { @cntproc[probefunc] = count(); } tick-1sec { trunc(@cntproc,10); printa(@cntproc); }
実行結果
sol11 $ sudo dtrace -s count_tuntap.d : 1 68057 :tick-1sec tunwsrv 678 tun_unitdata_ind.clone.0 9334 tunwput 35464 tun_frame 36333
tunwput はTCP/IPから転送されてきたフレームが渡されるエントリポイントで、tun_frame はその先でフレームのルーティング処理を行う関数です。tun_frame の右の数字36,333は転送時間(約10秒)の間に呼び出された回数です。送信するフレームが多くなれば当然呼び出される回数も増えるのでとくにこの結果からは目立ったことはありませんでした。
- TAPドライバ内の関数のトータル実行時間
elapsed_sum_tuntap.d
fbt:tap::entry { self->ts = timestamp; } fbt:tap::return /self->ts > 0/ { @ts[probefunc] = sum(timestamp - self->ts); self->ts = 0; } tick-1sec { trunc(@ts,10); printa(@ts); }
実行結果
sol11 $ sudo dtrace -s elapsed_sum_tuntap.d dtrace: script 'elapsed_sum_tuntap.d' matched 30 probes CPU ID FUNCTION:NAME : 1 68057 :tick-1sec tunwsrv 1081603 tun_unitdata_ind.clone.0 13908076 tunwput 32014047
一番 CPU時間を使った tunwput 関数のトータル実行時間が 32,014,047ns、つまり 0.032秒であったことを示しています。
先ほどの実行回数のところでも tunwput が出てきましたが、結果として10秒あたり 0.032 秒しか使ってないてないということで、TAP ドライバ側で時間がかかっている処理が有るわけでな無いようです。
OpenVPN プロセスのトレース
つづいてユーザプロセスである OpenVPN プロセスをトレースしてます。
- openvpnプロセス内での関数の呼び出し回数
count.d
pid$target:::entry { @cnt[probefunc] = count() } tick-1sec { trunc(@cnt, 30); printa(@cnt); }
実行結果
sol11 $ sudo dtrace -s count.d -p 5511 dtrace: script 'count.d' matched 11218 probes : BF_decrypt 66579 sha1_block_data_order 68652 EVP_CIPHER_CTX_iv_length 75084 po_ctl 75084 proto_is_dgram 81978 memset 223560 memcpy 243961 BF_encrypt 2032723
実行時間10秒の間に BF_encrypt が 2,032,723回呼ばれた事を示しています。2番目には memcpy が 243,961 回呼ばれています。
- openvpn内から呼ばれる関数の実行時間
elapsed_sum.d
pid$target:::entry { self->ts = timestamp; } pid$target:::return /self->ts > 0/ { @ts[probefunc] = sum(timestamp - self->ts); } tick-1sec { trunc(@ts,10); printa(@ts); }
実行結果
sol11 $ sudo dtrace -s elapsed_sum.d -p 5511 dtrace: script 'elapsed_sum.d' matched 22404 probes CPU ID FUNCTION:NAME : 1 68057 :tick-1sec SHA1_Update 142005693 memset 184523613 memmove 189561457 EVP_DigestUpdate 190132463 memcpy 316211424 BF_encrypt 1654880393 __pollsys 3503914650 _pollsys 3538953225 poll 3569561345 po_wait 3600229916
po_wait 関数は openvpn 自身の関数で名前の通り poll を呼び出して待ちます。Stack は以下のとおり。
sol11 $ sudo dtrace -n 'pid$target:::entry/probefunc=="poll"/{ustack(20)}' -p 5511 dtrace: description 'pid$target:::entry' matched 11217 probes CPU ID FUNCTION:NAME 0 77052 poll:entry libc.so.1`poll openvpn`po_wait+0x65 openvpn`io_wait_dowork+0x120 openvpn`main+0x35e openvpn`_start+0x83
これが全体の中で 3,600,229,916ns、つまり3約秒間とっています。
10秒の転送時間の中でトータル3秒間もデータの到着待ちしているとしたら非効率と言わざるを得ません。
snoop コマンドのトレース
上位プロトコルからのデータが届いていないのでは?との推測を受けて、snoop コマンドを使って TAP ドライバに流入するパケットをチェックします。
tap0 インターフェースに流れるパケットをファイル(バイナリフォーマット)に落とすコマンド実行例。
# snoop -d tap0 -o /var/tmp/snoop.out
このように snoop コマンドを実行しながら netperf コマンドを実行します。
取得したパケットキャプチャファイルは snoop コマンドでももちろん読めますが、よりグラフィカルにパケットの送受を確認するために Wireshark というパケットキャプチャの表示・解析ツールを使います。
Wireshark は多機能な解析ツールですが、その機能のなかでもパフォーマンス問題を調査するのにお奨めな機能が「Time-Sequence Graph(tcptrace)」です。この機能はキャプチャファイルオープン後、調査をしたいTCPコネクションのパケットを一つクリックした後、メニューの Statictics -> TCP Stream Graph -> Time-Sequence Graph(tcptrace)から起動することができます。
横軸が経過時間を示し、縦軸がそ転送されたデータ量を示しています。平らなっているように見える部分はデータ転送が無い部分です。
デフォルトでは全体を示しているのでわかりづらいのでマウスの左クリク、もしくは「i」キーでズームインします。
図中の「I」の一つが一つのパケットのデータ転送量を表しています。「I」が重なって上に伸びているのは連続してパケットが送信されたことを示しています。逆に「I」と次の「I」の間が開いてしまっているのは何らかの「待ち」が発生していることになります。
図の左上の方に斜め右上に階段上に登っている先は受信側が「Windowサイズ」として通知してきた受信可能なデータ量を示しています。
つまり、実際に「Windowsサイズ」と書かれた縦の赤線の高さくらいまで連続してデータを送ることができるのに、送信側(=クライアント)が送信を自ら止めているのです。
一方右下の階段上の線は受信側(=サーバ)からのとどいた確認応答(ACK)のデータを示しています。ある時間どのデータ量までACKを受けたかが分かります。
これらからわかることは、クライアントは、サーバからのある一定数のACK、実際には3~4つ前に送信したデータのACKが届くのを見届けてから次のデータを送信しているのが分かります。簡単に言うと以下のような動きを繰り返して、ちょっとずつ時間をロスしています。
- クライアントが4つのパケットを連続して送信。
- サーバからのACKを待つ(1msくらい)
- サーバからACKが到着。
- 次の4つのパケットを送信
TCP というプロトコルの仕組み上、送信側が通知してきた Window サイズ(図の赤い縦線)分だけのデータはACKを受けること無く、連続して送信することができるはずです。
では、なぜクライアントは 4つのパケットだけしか送信せずにACKを待っているのでしょう?
これはおそらくTCPの「輻輳回避アルゴリズム」が働いているため、と考えることができます。
輻輳回避アルゴリズムは、ネットワーク経路に輻輳が発生しているような場合に、ネットワークに負荷を掛けることによってパケットのロスが発生し、パケットの再送信が必要になる、という悪循環を避けるために、自らパケット送信のスロットルを弱める機能になります。
この場合、このパケット以前に、再送信が頻発するなど、TCPが「輻輳が発生している」と判断する事象が発生していたと考えられます。
では、あらためて、このTCP接続の最初の部分を見てみましょう。
これは、TCP接続の最初の部分です。最初「I」が3つならんで縦に伸びて言いますので、3つのパケットが連続してだされているのが分かります。続いては4つのパケットが連続で、次の次の塊では5つのパケットが連続で送られており、7つめ塊では7つのパケットが連続で送られている様子が見て取れます。先ほど書いた通り、本来はWindowサイズ分だけ一気にデータを連続して送れるはずですが、そうはしていません。なぜでしょう? これも輻輳回避の仕組みの一つで「スロースタート」といわれるTCPの機能です。TCPははじめからフルスロットルでデータの転送を開始すること無く文字通り「スロースタート」で様子を探りながらデータがどれくらいなら再転送せずに連続して送信できるかを確認しているのです。
そして、期待通り(?)問題が発生しています。真ん中付近でデータの再送信が発生している様子が見えます。このTime-Sequence 図では再送信がなければ「I」の高さが低くなることは無いはずで、最後の送信時より高さが低い「I」があったらそれは再送信を示しています。
そして、図の右上にあるようにサーバからの ACK が届かずにデータも送れない、という無通信状態が長く続いている様子が伺えます。
snoop の結果からの考察
データの送信状況をみると、Windowサイズが十分なのにもかかわらず、送信側であるクライアントがデータの送信を制御し、サーバからのACKを待っている様子が見える。また、TCP接続開始直後にスロースタートによって連続したデータ送信数を広げようとしている段階でデータの再送信や長期のACK待ちが発生している。これらにより、このTCP接続においてパケットのロスが頻発し、そのせいでパケットの再送信が発生し、その結果としてTCPの輻輳回避アルゴリズムによってデータの流出コントロールが行われたと考えられる。
コード調査
snoop の調査結果からパケットのドロップが起こっていることが推測されましたが、20Mbps程度のデータ量で NIC や Switch でバッファーオーバーフローが起こることは考えられないので、TAPドライバ自身の内部でパケットのドロップが起こっている可能性が出てきました。
実際には snoop のキャプチャにはパケットが記録できているので、疑わしいのは snoop にパケットを渡す部分と、openvpn プロセスにデータを転送する部分の間あたりだと推測できます。TAPのドライバのコードでその様なことを行なっているのは tun_frame という関数です。
/* Route frames */ ### パケットをルーティングする関数 static void tun_frame(queue_t *wq, mblk_t *mp, int q) { : /* Check for the sniffers */ ### snoop 等のパケットキャプチャ向けのルーティング処理 for( tmp=ppa->p_str; tmp; tmp = tmp->p_next ){ : if( !(str->flags & TUN_CONTROL) ){ ### openvpn プロセスにデータパケットをルーティングする処理 /* Data from the Protocol stream send it to * the Control stream */ DBG(CE_CONT,"tun: frame %lu -> control str\n", (ulong_t)msgdsize(mp)); if( canputnext(ppa->rq) ){ ^^^^^^^^^^^^^^^^^ putnext(ppa->rq, mp); ^^^^^^^^^^^^^^^^^^^ } else { if( q == TUN_QUEUE ){ DBG(CE_CONT,"tun: queueing frame %lu\n", (ulong_t)msgdsize(mp)); putbq(wq, mp); ^^^^^^^^^^^^^ } else { DBG(CE_CONT,"tun: dropping frame %lu\n", (ulong_t)msgdsize(mp)); freemsg(mp); ^^^^^^^^^^^ } } } else {
臭う部分がみえて来ました。下線をつけた canputnext(9F)というのは、引数で渡されたキュー(Streams Queue)にパケットが渡せるか?というのを確認するためのカーネルの関数です。ちょっと図で説明します。
今見ているのは図でアプリケーションからTAPドライバをつないでいる赤い矢印の下端部分です。TAPドライバはTCP/IP経由でアプリ(netperf)からのデータを受け取り、それを STREAM HEAD という門を通じて OpenVPN に渡そうかどうしようか、という判断をしている部分になります。
STREAM HEAD はユーザ空間とカーネル空間の間に居る特別なキューです。canputnext(9F) は図のSTREAMS HEAD にデータが渡せるかどうか(キューががいっぱいでないか)を確認するために使われています。
ここで、TAPではちょっと自分でも輻輳制御を行なっています。STREAM HEADのキューが一杯だとしても即座に、freemsg(9F)でパケットをドロップせず、一旦 putbp(9F) で自分自身のキューに保存し、2度めのチャレンジでもSTREAM HEADが一杯だったら初めて freemsg(9F) で破棄する、という動きをとっています。
・・・輻輳制御の仕組みがあるとは言え、非常に疑わしいコードです。デバッグプリントのコードを有効にして再度テストしてみましょう。
: Jul 16 22:19:15 sol11 tap: [ID 852863 kern.notice] tun: queueing frame 1389 Jul 16 22:19:15 sol11 tap: [ID 279187 kern.notice] tun: dropping frame 1389 Jul 16 22:19:15 sol11 tap: [ID 852863 kern.notice] tun: queueing frame 1389 Jul 16 22:19:15 sol11 tap: [ID 279187 kern.notice] tun: dropping frame 1389 Jul 16 22:19:15 sol11 tap: [ID 852863 kern.notice] tun: queueing frame 1389 Jul 16 22:19:15 sol11 tap: [ID 279187 kern.notice] tun: dropping frame 1389 Jul 16 22:19:15 sol11 tap: [ID 852863 kern.notice] tun: queueing frame 1389 Jul 16 22:19:15 sol11 tap: [ID 279187 kern.notice] tun: dropping frame 1389 :
案の定、ドロップの嵐です(笑)
なぜ、こんなにドロップしてしまうんでしょう? そもそも STREAM HEAD のキューのサイズってどれくらいなんでしょう?
チェックしてみましょう。
確認にはデバッガである mdb を使います。mdb に -k オプションを指定してカーネルデバッガとして起動します。(もちろんroot権限が必要です)
sol11 $ sudo mdb -k Loading modules: [ unix genunix specfs dtrace mac cpu.generic uppc pcplusmp scsi_vhci zfs mpt sd ip hook neti arp usba sockfs fctl kssl random idm fcip cpc crypto lofs ufs logindmux ptm sppp nfs ] >
ストリームの一覧を表示して TAP ドライバのストリームを探します。
> ::walk stream_head_cache|::stream : +-----------------------+-----------------------+ | 0xffffff015a80f6b8 | 0xffffff015a80f5c0 | | strwhead | strrhead | | | | | cnt = 0t0 | cnt = 0t0 | | flg = 0x00004022 | flg = 0x00044030 | +-----------------------+-----------------------+ | ^ v | +-----------------------+-----------------------+ | 0xffffff014d4988d0 | 0xffffff014d4987d8 | | tap | tap | | | | | cnt = 0t0 | cnt = 0t0 | | flg = 0x00248822 | flg = 0x00208832 | +-----------------------+-----------------------+
::walk stream_head_cache コマンドは全ての STREAMSをリストし、パイプで ::stream コマンドに渡すことで STREAMSの構造を見やすく図示してくれます。
右上の strrhead (STREAM HEAD の Read サイドキュー)のアドレスから queue のサイズ(q_hiwat)を見てみます。
ここでは queue_t 構造体の q_hiwat メンバを見てみます。
> 0xffffff015a80f5c0::print queue_t q_hiwat q_hiwat = 0x1400 ^^^^^^
::print コマンドは指定した与えられたアドレスをを構造体に当てはめて、指定したメンバを表示してくれるコマンドです。
なるほど、分かりました。キューのサイズは 0x1400=5,120byteです。TCPのペイロード(データ)が1,460byteだとすると、3パケット分しかキャッシュできない計算になります。これでは溢れるのも必至です。
コードの変更による対策
これまでの調査から、OpenVPN プロセスがオープンしている STREAM の STREAM HEADのキューのサイズ(q_hiwat)が小さいためにパケットのドロップが起きているのがわかっています。対策は単純で、このキューのサイズを大きくします。
具体的には OpenVPN が STREAM をオープンした際に呼ばれるコードに STREAM HEADのキューのサイズを大きするコードを追加します。
/* Handle IOCTLs */ static void tun_ioctl(queue_t *wq, mblk_t *mp) { : /* Set High Water Mark of Stream head */ if( !(mopt = allocb(sizeof(struct stroptions), BPRI_LO)) ){ tuniocack(wq, mp, M_IOCNAK, 0, ENOMEM); return; } mopt->b_datap->db_type = M_SETOPTS; mopt->b_wptr += sizeof(struct stroptions); sop = (struct stroptions *)(void *)mopt->b_rptr; sop->so_flags = SO_HIWAT; sop->so_hiwat = TUN_SO_HIWAT; putnext(ppa->rq, mopt);
so_hiwat に設定している TUN_SO_HIWAT は if_tun.h で以下のように宣言してあります。
#define TUN_SO_HIWAT 1024*1024
1024*1024byte。つまり1Mです。約720個のTCPデータを保持できます。これくらいあれば大丈夫でしょう。
コード変更後のパフォーマンス測定
結果
実ネットワークでの転送速度 | 1 Gbps |
OpenVPN+TAP ドライバ経由での転送 | 214 Mbps |
実際の出力
OpenVPN+TAP 経由
sol11 $ netperf -H 192.168.30.1 MIGRATED TCP STREAM TEST from ::ffff:0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.30.1 (192.168.30.1) port 0 AF_INET Recv Send Send Socket Socket Message Elapsed Size Size Size Time Throughput bytes bytes bytes secs. 10^6bits/sec 128000 49152 49152 10.04 214.29
どうでしょう? 変更前は 22Mbps 程度だったので約10倍ちかくスループットが向上しています。
実ネットワークとの差も 4.8 倍差と、目標としていた10分の1より縮まっています!!
というわけで、TUN/TAP ドライバのパフォーマンス改善までのデバッグ履歴は以上です。
なお、もし STREAM についてもう少し知りたいと言う方は拙作でありますが以下のページもご参照ください。
Hadoop 1.0.x の設定
Solaris 11 で Hadoop 1.0.x をセットアップしたときのメモです。
ソースダウンロード
インストール(ディレクトリのコピー)
ダウンロードした圧縮ファイルを展開し /usr/local にコピー。今後新しいバージョンに入れ替えるときのためにシンボリックリンクを設定
# cp -r hadoop-1.0.4 /usr/local # ln -s hadoop-1.0.4 hadoop # ls -ld /usr/local/hadoop lrwxrwxrwx 1 root root 12 1月 4日 11:47 /usr/local/hadoop -> hadoop-1.0.4
環境変数設定
PATH追加
Hadoop をコピーしたディレクトリの直ぐ下にある bin を PATH にセット
$ export PATH=$PATH:/usr/local/hadoop/bin
設定
/usr/local/hadoop/conf 以下の3つの設定ファイルを編集
なお、以下の設定では Hadoop がインストールされているホストのホスト名を sol11 としていますので適時読み替えてください。
core-site.xml
ファイルシステム名(fs.default.name)を設定
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <!-- Put site-specific property overrides in this file. --> <configuration> <property> <name>fs.default.name</name> <value>hdfs://sol11:9000</value> </property> </configuration>
hdfs-site.xml
NameNode のネームスペースとトランザクションログを格納するディレクトリ(dfs.name.dir) と、DataNode がブロックを格納するディレクトリ(dfs.data.dir)を設定
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>dfs.name.dir</name> <value>/var/tmp/hadoop/dfs/name</value> </property> <property> <name>dfs.data.dir</name> <value>/var/tmp/hadoop/dfs/data</value> </property> </configuration>
mapred-site.xml
JobTracker ホストのホスト名(mapred.job.tracker) を設定
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>mapred.job.tracker</name> <value>sol11:9001</value> </property> </configuration>
HDFS のフォーマット
$ hadoop namenode -format 13/01/04 09:48:03 INFO namenode.NameNode: STARTUP_MSG: /************************************************************ STARTUP_MSG: Starting NameNode STARTUP_MSG: host = sol11/127.0.0.1 STARTUP_MSG: args = [-format] STARTUP_MSG: version = 1.0.4 STARTUP_MSG: build = https://svn.apache.org/repos/asf/hadoop/common/branches/branch-1.0 -r 1393290; compiled by 'hortonfo' on Wed Oct 3 05:13:58 UTC 2012 ************************************************************/ 13/01/08 09:48:03 INFO util.GSet: VM type = 32-bit 13/01/08 09:48:03 INFO util.GSet: 2% max memory = 17.81375 MB 13/01/08 09:48:03 INFO util.GSet: capacity = 2^22 = 4194304 entries 13/01/08 09:48:03 INFO util.GSet: recommended=4194304, actual=4194304 13/01/08 09:48:03 INFO namenode.FSNamesystem: fsOwner=kaizawa 13/01/08 09:48:03 INFO namenode.FSNamesystem: supergroup=supergroup 13/01/08 09:48:03 INFO namenode.FSNamesystem: isPermissionEnabled=true 13/01/08 09:48:03 INFO namenode.FSNamesystem: dfs.block.invalidate.limit=100 13/01/08 09:48:03 INFO namenode.FSNamesystem: isAccessTokenEnabled=false accessKeyUpdateInterval=0 min(s), accessTokenLifetime=0 min(s) 13/01/08 09:48:03 INFO namenode.NameNode: Caching file names occuring more than 10 times 13/01/08 09:48:04 INFO common.Storage: Image file of size 113 saved in 0 seconds. 13/01/08 09:48:04 INFO common.Storage: Storage directory /var/tmp/hadoop/dfs/name has been successfully formatted. 13/01/08 09:48:04 INFO namenode.NameNode: SHUTDOWN_MSG: /************************************************************ SHUTDOWN_MSG: Shutting down NameNode at sol11/127.0.0.1 ************************************************************/
起動
hadoopの各デーモンの起動
sol11 % /usr/local/hadoop/bin/start-all.sh starting namenode, logging to /usr/local/hadoop-1.0.4/libexec/../logs/hadoop-kaizawa-namenode-sol11.out localhost: starting datanode, logging to /usr/local/hadoop-1.0.4/libexec/../logs/hadoop-kaizawa-datanode-sol11.out localhost: starting secondarynamenode, logging to /usr/local/hadoop-1.0.4/libexec/../logs/hadoop-kaizawa-secondarynamenode-sol11.out starting jobtracker, logging to /usr/local/hadoop-1.0.4/libexec/../logs/hadoop-kaizawa-jobtracker-sol11.out localhost: starting tasktracker, logging to /usr/local/hadoop-1.0.4/libexec/../logs/hadoop-kaizawa-tasktracker-sol11.out
動作テスト
HDFS のテスト
messages ファイルを HDFS に保存してみる
$ hadoop dfs -copyFromLocal /var/adm/messages /
HDFS上の message ファイルの中を読んでみる
$ hadoop dfs -cat /messages Apr 15 13:18:49 sol11 sendmail[1102]: [ID 702911 mail.crit] My unqualified host name (sol11) unknown; sleeping for retry Apr 15 13:19:49 sol11 sendmail[1102]: [ID 702911 mail.alert] unable to qualify my own domain name (sol11) -- using short name
Hadoop のテスト
Hadoop の添付されているサンプルを使って円周率を求める
$ cd /usr/local/hadoop $ % hadoop jar hadoop\-examples\-1.0.4.jar pi 1 10 Number of Maps = 1 Samples per Map = 10 Wrote input for Map #0 Starting Job 13/01/08 09:57:20 INFO mapred.FileInputFormat: Total input paths to process : 1 13/01/04 09:57:20 INFO mapred.JobClient: Running job: job_201301080948_0001 13/01/04 09:57:21 INFO mapred.JobClient: map 0% reduce 0% 13/01/04 09:57:40 INFO mapred.JobClient: map 100% reduce 0% 13/01/04 09:57:56 INFO mapred.JobClient: map 100% reduce 100% 13/01/04 09:58:01 INFO mapred.JobClient: Job complete: job_201301080948_0001 13/01/04 09:58:01 INFO mapred.JobClient: Counters: 27 13/01/04 09:58:01 INFO mapred.JobClient: Job Counters 13/01/04 09:58:01 INFO mapred.JobClient: Launched reduce tasks=1 13/01/04 09:58:01 INFO mapred.JobClient: SLOTS_MILLIS_MAPS=19266 13/01/04 09:58:01 INFO mapred.JobClient: Total time spent by all reduces waiting after reserving slots (ms)=0 13/01/04 09:58:01 INFO mapred.JobClient: Total time spent by all maps waiting after reserving slots (ms)=0 13/01/04 09:58:01 INFO mapred.JobClient: Launched map tasks=1 13/01/04 09:58:01 INFO mapred.JobClient: Data-local map tasks=1 13/01/04 09:58:01 INFO mapred.JobClient: SLOTS_MILLIS_REDUCES=14567 13/01/04 09:58:01 INFO mapred.JobClient: File Input Format Counters 13/01/04 09:58:01 INFO mapred.JobClient: Bytes Read=118 13/01/04 09:58:01 INFO mapred.JobClient: File Output Format Counters 13/01/04 09:58:01 INFO mapred.JobClient: Bytes Written=97 13/01/04 09:58:01 INFO mapred.JobClient: FileSystemCounters 13/01/04 09:58:01 INFO mapred.JobClient: FILE_BYTES_READ=28 13/01/04 09:58:01 INFO mapred.JobClient: HDFS_BYTES_READ=238 13/01/04 09:58:01 INFO mapred.JobClient: FILE_BYTES_WRITTEN=43307 13/01/04 09:58:01 INFO mapred.JobClient: HDFS_BYTES_WRITTEN=215 13/01/04 09:58:01 INFO mapred.JobClient: Map-Reduce Framework 13/01/04 09:58:01 INFO mapred.JobClient: Map output materialized bytes=28 13/01/04 09:58:01 INFO mapred.JobClient: Map input records=1 13/01/04 09:58:01 INFO mapred.JobClient: Reduce shuffle bytes=0 13/01/04 09:58:01 INFO mapred.JobClient: Spilled Records=4 13/01/04 09:58:01 INFO mapred.JobClient: Map output bytes=18 13/01/04 09:58:01 INFO mapred.JobClient: Total committed heap usage (bytes)=245891072 13/01/04 09:58:01 INFO mapred.JobClient: Map input bytes=24 13/01/04 09:58:01 INFO mapred.JobClient: Combine input records=0 13/01/04 09:58:01 INFO mapred.JobClient: SPLIT_RAW_BYTES=120 13/01/04 09:58:01 INFO mapred.JobClient: Reduce input records=2 13/01/04 09:58:01 INFO mapred.JobClient: Reduce input groups=2 13/01/04 09:58:01 INFO mapred.JobClient: Combine output records=0 13/01/04 09:58:01 INFO mapred.JobClient: Reduce output records=0 13/01/04 09:58:01 INFO mapred.JobClient: Map output records=2 Job Finished in 41.727 seconds Estimated value of Pi is 3.60000000000000000000
本家設定ページ
Solaris 11: リカバリー目的で ZFS を起動する方法
後述のマニュアルにまんま載ってますが一応書いておきます。
- Solaris 11 インストール CD から起動する
- ターミナルから root pool をインポートする
# zpool import -f rpool - /a に ZFS ブート環境をマウントする
# beadm mount solaris /a
How to Boot ZFS for Recovery Purposes
ESXi のゲスト Windows マシン上でネットワークブリッジを使えるようにする
ESXi 上の Windows ゲストでネットワークブリッジの設定をする際にうまく行かず悩んだ点があったのでエントリ書いておきます。
Windows XP 以降には「ネットワークブリッジ」という機能があり、Windows マシン上に繋がった別々のネットワークを1つのネットワークとして結合することができます。
想定しているネットワーク構成のイメージは以下のようなものです。
ESXi のゲストとして、HostA、HostB という2つの Windows ゲストがあって、それぞれが別々の仮想スイッチ(vSwitch)につながっている状態です。ここで、2つのネットワークアダプタを持ち双方の仮想スイッチに繋がった BridgeHost というWindowsゲストを配置してそれぞれのネットワークを Windows のネットワークブリッジ機能を使って結合し、HostA と HostB が BridgeHost を介して通信できるようにする、というのが目標です。
実マシンとスイッチで構成されていれば、上図のように2つのネットワークアダプタを追加したネットワークブリッジを作成*1すれば、期待通りにブリッジされて HostA と HostB は同じネットワークに繋がっているかのように通信することができます。
ところが、ESXi のゲストの場合は、この設定だけでは HostA と Host B は通信することができません。
具体的に言いますとブロードキャストのイーサネットフレームは相手側に到達しますが、双方のネットワークアダプタの Mac アドレス宛のイーサネットフレームが BridgeHost を通過できません。(というより BridgeHost にも到達しません)
例えば HostA から HostB に ping コマンドを打った場合。
- HostA は HostB の Mac アドレスを解決するべくブロードキャスト宛に ARP リクエストを投げる
- BridgeHost はブロードキャスト宛の ARP リクエストを受け取り、HostB の居る vSwitch1 に ARP リクエストを転送する。
- HostB は ARP リクエストを受け取り、HostA の Mac アドレス宛に ARP リプライを送信する。
- しかし HostA 宛の ARP リプライは BridgeHost には届かず、したがって HostA にも転送されない。
- HostA は ARP リクエストを再送を繰り返すが、リプライは受け取れない…
これは ESXi の vSwitch のセキュリティ設定にて「無差別モード」がデフォルトで拒否になっている為です。つまり vSwtich としては BridgeHost 宛で無い(HostA宛)のイーサネットフレームを BridgeHost のネットワークアダプタに転送しないようになっているのです。
これを変更するためには以下の要領で vSwitch の設定を変更する必要があります。
セキュリテイタブより「無差別モード」を「承諾」に変更して「OK」をクリックします。
これで期待通り、HostA 宛、HostB 宛 のイーサネットフレームが BridgeHost を通過することができるようになり、HostA と HostB が通信できる様になります。なお、BridgeHost がブリッジ接続するアダプタに繋がった全ての vSwitch の設定を変更する必要があります。*2
ご参考
vSphere Clinet のオンラインヘルプによると以下のように説明されています。
vSphere 標準スイッチのセキュリティ ポリシーの編集
レイヤー 2 は、データ リンク レイヤーです。レイヤー 2 セキュリティ ポリシーの 3 つの要素は、 無差別モード、MAC アドレス変更、および偽装転送の 3 つです。無差別モード以外では、ゲスト アダプタは、自身の MAC アドレスのトラフィックのみを検出します。無差別モードでは、すべて のパケットを検出できます。デフォルトでは、ゲスト アダプタは無差別モード以外に設定されます。
無差別モードオプション
拒否 | ゲスト アダプタを無差別モードに設定しても、アダプタが受信するフレームには影響しません。 |
承諾 | ゲスト アダプタを無差別モードに設定すると、アダプタに接続するポート グループの VLAN ポリシーが許可する vSphere 標準スイッチを通過したすべてのフレームが検出されます。 |
Windows のネットワークブリッジについてはこちらが詳しいです。
Windows XP ネットワーク ブリッジの動作概念
Solaris 11 Early Adopter でのパッケージのインストール
先日 Solaris11 Early Adoperがリリースされました。既存のコードが Solaris11 EA 上でビルド可能か確認しようとさっそくインストールしたのですが、pkg(1M) コマンドを使ったネットワーク経由での gcc や ヘッダファイル等のパッケージのインストールがエラーになってしまい困っておりました。
# pkg install developer/opensolaris/X Creating Plan / pkg install: No matching version of developer/opensolaris/X can be installed: Reject: pkg://solaris/developer/opensolaris/X@0.5.11,5.11-0.151:20101026T181446Z Reason: All versions matching 'require' dependency pkg:/compatibility/ucb are rejected Reject: pkg://solaris/compatibility/ucb@0.5.11,5.11-0.151.0.1:20101104T230637Z Reason: This version is excluded by installed incorporation pkg://solaris/consolidation/osnet/osnet-incorporation@0.5.11,5.11-0.173.0.0.0.0.17656:20110826T144402Z
その事を twitter 上でつぶやいたところ @mayn_lum さんからローカルレポジトリからパッケージのインストールする方法を教えて頂き、さっそく試したところようやく必要なパッケージのインストールできたので、こちらに簡単な手順を紹介しておきます。(@mayn_lum さんいつもありがとうございます!)
なお、ネットワーク経由でのパッケージがインストール失敗する根本の原因(パッケージ名違い?)はわかっていません。
もしうまくいく方法がありましたら教えて下さい。(おそらくEA 版だけの問題だとおもうのですが)
パッケージアーカイブの入ったリポジトリイメージをダウンロード
パッケージファイルは2つの zip ファイルに分割して配布されているので Solaris11 EA のページ の「Oracle Solaris 11 Early Adopter Repository Image」という部分から以下の2つのリンクをクリックして、それぞれ sol-11-ea-repo-full-iso-a.zip と sol-11-ea-repo-full-iso-b.zip というファイルをダウンロードする。
Download Part A SPARC, x86 (2 GB) Download Part B SPARC, x86 (2 GB)
ファイルの統合
ダウンロードした zip ファイルを解凍した後、cat(1M) コマンドで一つファイルに連結します。
連結後の ISO ファイルのサイズはだいたい 6.1GB ほどです。
$ unzip sol-11-ea-repo-full-iso-a.zip $ unzip sol-11-ea-repo-full-iso-b.zip $ cat sol-11-ea-repo-full-iso-a sol-11-ea-repo-full-iso-b > sol-11-ea-repo-full.iso
ISO ファイルをブロックデバイスに関連付け
パッケージのISOファイルの中身をこのあとの集積サーバーで利用するために、lofiadm(1M) コマンドを使って ISOファイルをブロックデバイスに関連付けします。
ここからは root 権限が必要です。
# /usr/sbin/lofiadm -a /repo/sol-11-ea-repo-full.iso /dev/lofi/1
ブロックデバイスをマウント
関連付けを行ったブロックデバイスをマウントします。
ここでは /mnt にマウントしていますが他もディレクトリでも大丈夫です。
# /usr/sbin/mount -F hsfs /dev/lofi/1 /mnt
集積サーバの設定
先ほどマウントしたリポジトリデータの場所を指定して Image Packaging System の集積サーバを設定します。
inst_root には先ほどマウントしたマウントポイント /mnt の下の repo というディレクトリを指定しています。もし /mnt 以外のところにマウントしている場合には inst_root=
# /usr/sbin/svccfg -s application/pkg/server setprop pkg/inst_root=/mnt/repo # /usr/sbin/svccfg -s application/pkg/server setprop pkg/readonly=true
集積サーバの起動
Image Packagin System の集積サーバを起動します。
起動には svcadm(1M) コマンドを使用します。これによって集積サーバはデフォルトで TCP ポート 80 番で接続を待機します。
# /usr/sbin/svcadm refresh application/pkg/server # /usr/sbin/svcadm enable application/pkg/server
パッケージ配布元の設定
pkg コマンドに配布元(パブリッシャー)の場所をセットします。
上記の通りに設定した場合には場所は http://localhost になります。
# pkg set-publisher -O http://localhost solaris
これで以降の pkg コマンドの実行時にはパッケージはローカルのパッケージから取得されるようになります。
私もこれで無事 gcc のインストールができました。
このエントリは基本的に下記の記述を参考に書いています。あわせてこちらもご参照下さい。
Oracle SolarisTM 11 Early Adopter Release Repository Image
Nゲージ高架レイアウト作成記2
Nゲージレイアウト作成記第三弾。1400x700 のレイアウトです。
ストラクチャやレールを買うだけ買って進んでなかったのですが先週、今週と作業しました。
今回やったのは以下です。
高架などのストラクチャの墨入れとウェザリング
買ったばかりなのに勿体無い。と思われますがリアルさのため墨入れとウェザリングを行います。
墨入れは、ストラクチャの溝に薄く溶いた黒の塗料を流しこんで、光の明暗を表してリアルに見せるテクニックです。
ウェザリングは風雨にさらされたように見せる塗装のテクニックです。
実は単に墨入れしようとしたら下地と同じ溶剤の塗料でやってしまったためにはみ出た分をきれいに拭き取れずそのままウェザリングということにしてしまったことはないしょです。(笑)
写真の階段部分のレンガの筋がはっきり見えているのが墨入れの効果です。看板の周りとかもなんとなく風雨にさらされた雰囲気がでているかなー?と。
ちなみに駅名の「新小山」はJR総武線の新小岩からインスパイアされてます。このレイアウトのモデルが小岩、新小岩なので。
屋根もこんな感じ。息子にはやりすぎと言われました。そうかも。
道路となる厚紙の貼付け
今まで作ってきたレイアウトと違い近郊駅のイメージのレイアウトなので基本地面は舗装路になります。もちろん道幅に合わせて貼りつけててもいいのですが、めんどくさいので一気に道路用の厚紙を貼り付けました。貼りつけたのは東急ハンズでかってきた灰色の厚紙。買ったときは大きいなぁとおもっていたんですけど貼りつけてみたら意外に小さかったです。
貼付けは2倍に薄めた木工用ボンドをハケでベースのベニア板に塗っていきます。決して厚紙側に塗ってはダメです。ヘニャヘニャになります。泣 (経験済み)
ベニアにボンド水が染みこむので思ったよりボンドが必要で焦りました。
ボンド水をまんべんなく塗ったら厚紙を貼っていきます。しっかり着くように布巾などでゴシゴシこすっていきます。決して素手でやってはダメです。どっかでついたボンドが厚紙について台無しになります。泣 (経験済み)
貼ったあとがこちら。貼ってない上側は土手になる予定です。
高架盛土用のスタイロフォームの整形
高架線路の反対側は盛土にする予定です。なので土手用にスタイロフォーム(堅い発泡スチロール)を整形します。
なんで盛土にしたかというと変化をつけたかったのと高架線路が高いからです。
こちらが完成したもの。
発泡スチロールをきれいに切断するのは意外に骨が折れます。
ホントはこんな工具があれば楽なんですけどねー。
- 出版社/メーカー: 白光
- メディア: Tools & Hardware
- クリック: 6回
- この商品を含むブログ (1件) を見る
そんな訳でこちらが現在の全景。
駅も結構細かいとこまであるんですよ。シールを張ってちょっと賑やかに。
今回買ったもの
最後に今回買ったものたちです。
Nゲージレイアウト ジオコレ一式 | 3,600 |
塗料 | 4,507 |
ストラクチャ(一軒家) | 1,200 |
両渡ポイントレール | 5,292 |
ポイントレール | 1,890 |
小計 | 16,489 |
これまでの出費: 44,248円
ひえ〜両渡りポイントレール高い><
Nゲージ ユニトラック線路 複線両渡りポイント (ダブルクロス) #20-210
- 出版社/メーカー: カトー
- メディア: おもちゃ&ホビー
- クリック: 8回
- この商品を含むブログ (1件) を見る