Cloudy Days

クラウドコンピューティングにまつわる話をつれづれなるままに。。。

2009年7月1日水曜日

EC2でkexecできないか?

EC2ではAMIをカスタマイズできるし、たくさんのAMIがアップロードされているけど、カーネルはあらかじめ用意されたAKI (Amazon Kernel Image)を使う必要がある。現状では、AKIはAmazonか一部のベンダにしか作れないようだ。それならば、kexecを使ってカーネルを起動してやればいいのではと考えたが、結論としてはうまくいかなかった。

kexecは現在起動中のカーネルとは別カーネルを起動する仕掛けで、BIOSやブートローダをスキップできるので、再起動が高速化される。特に高いサーバマシンになるほどBIOSの処理時間が長くなるので、頻繁にリブートが必要なときは便利な機能だ。また、kexecを利用したkdumpというカーネルダンプ機能もある。詳細は、「Kexecを使ってLinuxの起動を早める」などを参照のこと。

kexecを使うにはカーネルが対応していることはもちろん、kexec-toolsというパッケージをインストールする必要がある。大まかな動作の流れとしては、新しく起動するカーネルイメージをメモリにロードし、リブートという2段階になる。

で、早速EC2のインスタンス上で実行してみたところ、kexec -lでカーネルイメージをロードする段階で失敗してしまった。

[root@domU-12-31-39-03-2C-55 ~]# kexec -l --initrd=/boot/initrd-2.6.21.7-5.fc8xen.img \
--append='root=/dev/sda1 ro 4' /boot/vmlinuz-2.6.21.7-5.fc8xen
Invalid memory segment 0xc1000000 - 0xc12d3fff


一方、手元のCentOS 5.3環境で実行してみたところ、kexecの実行までは行くのだが、VMがシャットダウンしてしまった。

# kexec -l --append='root=/dev/xvda1 ro console=hvc0 xencons=tty' --console-serial /boot/vmlinuz-2.6.26
# kexec -e
Starting new kernel


ログ(/var/log/xen/xend.log)には、次のメッセージが出力されていた。

INFO (XendDomainInfo:994) Domain has shutdown: name=lenny id=3 reason=poweroff.


むぅ、domUのkexecってちゃんと対応されているものなのかな?ちなみに、Xenのバージョンは、EC2が3.0.3-rc5-8.1.14.eで、CentOSが3.1.2-128.1.14.el5。

関連情報

2009年6月24日水曜日

Amazon EC2事始め

実際に動かしてみないとよくわからないので、遅ればせながらAmazon EC2をさわってみた。

まずは、何はなくともAWS (Amazon Web Services)のアカウントを作る。そして、X.509証明書も作っておく。

EC2を簡便に利用するためにElasticfoxというFireboxプラグインが存在することは知っていたけど、このためだけにFirefoxを使うのもなぁと思っていたら、最近はAmazon Management Consoleというサービスがあるようだ。両者の違いはわからないけど、AMI(Amazon Machine Image)の検索から、インスタンスのライフタイム管理、Elastic IPなどの設定など、必要そうな機能はそろってそうだ。

Amazon Management Consoleにサインインすると、ダッシュボードが表示されるので、さっそくAMIを探す。コミュニティで作られたAMIは2630個もあってとても選んでられないので、とりあえずQuick StartにあるFedora 8を選択し、インスタンスを起動する。すると、まずAMIにSSHログインするために必要なキーペアを作ることになる。ここでプライベートキーがダウンロードされるんだけど、なぜか下のスクリーンショットのように、「Loading, please wait...」のダイアログが消えずに残ったままになっている。ぜんぜん終わらないなと、しばらく待惚けしてしまった。



あとはファイアウォールの設定をするとインスタンスが起動する。Consoleのステータスを見る限り、インスタンスの起動に50秒、終了に30秒ぐらいかかっているようだった。

さて、さきほどダウンロードしたキーペアを利用して、sshログインしてみる。

$ chmod 400 qstest.pem
$ ssh -i qstest.pem root@ec2-174-129-178-172.compute-1.amazonaws.com

__| __|_ ) Fedora 8
_| ( / 32-bit
___|\___|___|

Welcome to an EC2 Public Image
:-)

Getting Started

--[ see /etc/ec2/release-notes ]--

[root@domU-12-31-39-00-54-94 ~]# uname -a
Linux domU-12-31-39-00-54-94 2.6.21.7-2.fc8xen #1 SMP Fri Feb 15 12:39:36 EST 2008 i686 athlon i386 GNU/Linux


インスタンスはスモール(1時間0.10 USD)を選択したが、CPUは低消費電力版AMD Opteron 2.6GHz(と/proc/cpuinfoでは見えるが、Xenによって1.0から1.2 GHz相当に制限がかかっているかもしれない。コアあたり2個ぐらいインスタンスがわりあてられるとか)、メモリは1.7GBになる。日本とのRTTは200ミリ秒程度。

[root@domU-12-31-39-00-54-94 ~]# cat /proc/cpuinfo
processor : 0
vendor_id : AuthenticAMD
cpu family : 15
model : 65
model name : Dual-Core AMD Opteron(tm) Processor 2218 HE
stepping : 3
cpu MHz : 2599.998
cache size : 1024 KB
fdiv_bug : no
hlt_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 1
wp : yes
flags : fpu tsc msr pae mce cx8 apic mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt rdtscp lm 3dnowext 3dnow up pni cx16 lahf_lm cmp_legacy svm extapic cr8legacy ts fid vid ttp tm stc
bogomips : 6502.82
clflush size : 64

[root@domU-12-31-39-00-54-94 ~]# cat /proc/meminfo
MemTotal: 1747764 kB
MemFree: 1446716 kB
Buffers: 217076 kB
Cached: 33748 kB
SwapCached: 0 kB
Active: 23096 kB
Inactive: 234136 kB
HighTotal: 1003528 kB
HighFree: 953652 kB
LowTotal: 744236 kB
LowFree: 493064 kB
SwapTotal: 917496 kB
SwapFree: 917496 kB
Dirty: 40 kB
Writeback: 0 kB
AnonPages: 6416 kB
Mapped: 5616 kB
Slab: 8912 kB
SReclaimable: 4568 kB
SUnreclaim: 4344 kB
PageTables: 960 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
CommitLimit: 1791376 kB
Committed_AS: 42364 kB
VmallocTotal: 114680 kB
VmallocUsed: 1360 kB
VmallocChunk: 112936 kB


さて、sshログインに必要な設定(/root/.ssh以下のパブリックキーおよびauthorized_keys)は、/etc/rc.localから呼ばれるシェルスクリプト経由で実行される。あと、ec2-ami-tools RPMもインストールされる。この辺は自分でAMIを作るとしたら押さえておく必要があるな。

(追記)ちょっと勘違いしていた。シェルスクリプト(/usr/local/sbin/get-credentials.sh)は、sshでログインできるように、最初に作ったキーペアのパブリックキーをcurlでダウンロードしてきて、authorized_keysに書き込むという処理を行う。サーバ側はIP要求者のIPアドレスでも見て、どのキーペアを利用しているかをチェックしているのだろうか?
このあたりの挙動は「Amazon EC2の機能を詳しく見てみる(3)--インスタンスデータとAMI」に詳しい。RESTインタフェースによってインスタンスのデータを取得できるとのこと。

2009年6月11日木曜日

Java NIO FileChannel

Hadoopコードリーディング大会その1。

HDFSのDataNodeに対してブロックリードのリクエストを出すと、デフォルトではNIOのチャネルが使われる(もう一つは昔からあるストリームIOを使う実装)。このチャネルのtransferToメソッドはUNIXのsendfileシステムコールみたいなものだ。(裏は取ってないが)実際、内部はsendfileを使って実装されているという記述も見かけた。sendfileはファイルをユーザプロセス空間にコピーすることなく、カーネル内で直接ソケットに書き込んでしまう仕組み。(少なくとも現状では)ファイルからソケットへの書き込みにしか対応していないので、transferFromメソッドはsendfileを使っては実装できない。おそらく、mmapしてからwriteしているのだろう。

今までNIOを使ったことがなかったので、FileChannel.transferTo、transferFromを使ったファイル転送ベンチマークを書いてみた。ソースはここのそれらしいファイル。

1GBファイルを転送したときのスループットが40 MB/sぐらい。ちなみにHDDはMaxtor 7L250S0で、hdparm -tで測ったread性能が63 MB/s、ddで1 GBファイル作ったときが68 MB/s。

この機会にJavaのソケットAPIを少し調べてみたが、Java 1.4になってから、CのソケットAPIでできることは大抵できるようになった気がする。

2009年6月4日木曜日

Jettyのバルクデータ転送性能

Hadoopで内部的にも使われているHTTPサーバJettyの性能を測ってみた。HDFSのブロックサイズは64MBだったと思うので、まずは64MBのファイルをwgetで取得した際のスループットを測った(ちなみにGFSのチャンクのことをHDFSではブロックと呼ぶ)。比較対象としてC言語で実装されたApacheとlighttpdでも同様の実験を行った。なお、ネットワークはGbEで、Iperfで941 Mbps出ることを確認している。Jettyのバージョンは6.1(Hadoop0.19.1に同梱されていのは5.1.4)、ApacheはCentOS標準の2.2.3、lighttpdは1.4.22。

その結果、共に896Mbpsと遜色ない値を示した。

さらに(現実的なシナリオとは言えないけど)ファイルサイズを1GBにしてみた。今回のサーバは1GBのメモリしか積んでないので、ファイル全体がメモリに載らず、性能はディスクで律速するはずである。結果はややばらついたので、それぞれ5回実行した結果を下表に示す。単位はMbps。







12345
Jetty 6.1380.8416.0395.2380.0404.8
Apache 2.2.3262.4264.8263.2256.0252.0
lighttpd 1.4.22251.2244.0252.8248.8250.4


意外なことにJettyが勝っている。いったい何が影響しているのだろうか?特に設定ファイルはいじっていない。ディスクキャッシュの影響かなぁ。よくわからない。

実験をやった後に知ったのだけど、ブロックの転送にHTTPは使われてなさそうで、JettyはJobTrackerのモニタリング機能のために使われているようだ。DataNodeとHDFSクライアント間の通信はTCP/IP通信で、データは64KBのパケットに分割されてから送信される。パケットは512バイトごとにチェックサムが計算される。そもそも、(絶対条件ではないが基本的に)データが存在するノードでタスクが実行されるので、リモートノードと通信は起きないはずだ。

参考までに両者の輻輳ウィンドウの挙動を、TCP Probeモジュールを使って確認してみた。通信開始時は両者に違いがないように見えるが、観測したスループットはこの時点ですでに差がついているんだよな。Linuxカーネルのバージョンは2.6.18で、TCPはBIC(ssthreshの初期値は100)を使っている。TCP関連のパラメータはOSでフォルト設定から特にいじってない。


余談。JettyのコンパイルにはMavenが必要で、デフォルト設定だとビルド時にヒープが足りなくなるので、環境変数MAVEN_OPTSに-Xmx128mなどと指定する必要があった。

2009年6月2日火曜日

Hadoop 0.19.1インストール

今、Hadoopのページを見ると、0.18.3、0.19.1、0.20.0の三つのリリースが存在する。最新版を追っかける気もしないので、0.19.1あたりを試すことにする。Release notesなどを眺めると0.19.0でappendに対応したけど、0.19.1で無効に戻したとかある。データが消えてしまう深刻なバグがあるので0.19.0は使ってはいけないようだ。あと、0.20になるとconfiguration file (hadoop-site.xmlとか)が複数ファイルに分割されたりと変更されている。

さて、早速インストール。実験環境は8ノードのPCクラスタ(ホスト名はnode00-07)で、ホームディレクトリはNFSで共有され、SSHはホストベース認証が設定済み。JDK 1.6.0_13。環境変数JAVA_HOMEは別途.zshenvで設定済みなので、conf/hadoop-env.shはいじらない。

以下は、クラスタ環境での設定メモ。

設定ファイルはconfディレクトリ以下に存在し、サイトごとの設定はhadoop-site.xmlで行う。


conf/hadoop-site.xml:
<configuration>
<property>
<name>fs.default.name</name>
<value>hdfs://node00:54310</value>
</property>
<property>
<name>mapred.job.tracker</name>
<value>node00:54311</value>
</property>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
</configuration>


マスターノードとスレーブノードはそれぞれ以下のファイルにホスト名を列挙しておく。


conf/masters:
node00

conf/slaves:
node00
node01
node02
node03
node04
node05
node06
node07


HDFSのフォーマット


$ bin/hadoop namenode -format


Hadoopの起動


$ bin/start-all.sh


念のため、jpsコマンドでマスターノードにJobTrackerとNameNode(とSecondaryNameNode)、スレーブノードにTaskTrackerとDataNodeが起動していることを確認する。

Hadoopの終了


$ bin/stop-all.sh


MapReduceの実行

Quick Startの例を実行してみる。まずはconfディレクトリの内容をHDFSにコピーする。


$ bin/hadoop fs -put conf input


サンプルのgrepを実行。HDFS上のinputからファイルを読み込み、結果をoutputに出力する。


$ bin/hadoop jar hadoop-*-examples.jar grep input output 'dfs[a-z.]+'


出力をローカルファイルに出力する。


$ bin/hadoop fs -get output output


蛇足だけど、httpdにはJettyを使っている。

2009年5月26日火曜日

Javaのネットワーク性能ベンチマーク

Javaのネットワーク性能を測るベンチマークが欲しかったのだが、探してもすぐに見つからなかったので、簡単なのを書いてみた。というのもHadoopはJavaで実装されているが、通信性能がJavaが原因で律速されないか確認したかったから。

実験環境はXeon/3.0GHz dual搭載のPC 2台をGbEで接続したものである。OSはCentOS 5.3で、JDKは1.6.0_13。Iperfでは944 Mbps出ている。結論から言うと、Javaでも941 MbpsとCと遜色ない性能が得られた。

実験結果を下に示す。横軸はメッセージサイズ(writeサイズ)で、縦軸はグッドプット。きわめてリーズナブルな結果。



#ソースコードのコピペ方法がよくわからんな。(後で直す)

githubにソースコードを置いたので、こちらを参照してほしい。

2009年5月22日金曜日

羊の皮を被った狼

hyoshiokさんがクラウドについて書いていた。
クラウド時代の計算パラダイムがRDBMSが30年間研究開発していたACIDパラダイムからCAPパラダイムへ大きく舵を切ったという意味で面白い。ちょうどコンピュータアーキテクチャにおける、CISCパラダイムからRISCパラダイムへ変遷していったようなイメージと重なる。


CAP定理/BASEに関してはあちこちで書かれているのでここでは繰り返さないが、yohei-yさんのまとめが目に止まった。Eric Brewer教授は検索エンジン会社inktomiの創設者でもあるのだが、CAP定理/BASEの登場にはこのような背景があったのね。
AltaVista が DEC の Alpha サーバの性能を売りにした scale-up 的アプローチだったのに対し、inktomi は Scale-out 的アプローチを取ったのが(AltaVistaに対する)技術的な成功要因だったようだ。Brewer のスライドの写真を見ると、時期的にはどうやら Sun の UltraSparc II のクラスタを構築していたようだ。これはまさに僕がNAISTの自席で使っていたワークステーションだけれど、CPUが250MHzで640MBメモリを搭載していたと記憶している。
inktomiが取ったこのscale-out戦略ベースのアーキテクチャは今のWebの大規模分散システムの根源となるアーキテクチャとなっている。

クラウドは技術的に考えれば、並列分散コンピューティング技術である。その前に流行ったグリッドも同様で、技術的に両者を比較するのはあまり意味がないことのようにも思える。個人的には、クラウドの要素技術がデータセンタ(クラスタ)内の分散並列であるのに対して、グリッドは広域分散に寄っていというイメージを抱いているが、クラウドも広域分散にシフトするのは時間の問題だろう。

さて、並列分散というと、いわゆるHPC(ハイパフォーマンスコンピューティング)分野を思い浮かべる人がいるかもしれない。MPIとかOpenMPとかの世界で、(適切な喩えかわからないが)CAP定理/BASEではなくACID寄りの世界観を持つ。現時点でHPCユーザはクラウドなんて性能がでないから使えないと思っているだろうが、そんな前提はいつまで有効なのか実はわからない。HPCユーザは性能がでるのであれば、ベクトルマシンからPCクラスタ向けにコードを移植したように、クラウド向けに再チューニングしてくるだろう。余談だけど、MPIなんてそんなにスケールアウトしないでしょうと思ったら、RoadrunnerとかRangerといった何万コアの計算機で動いているという現実に驚く。

もちろんすべての問題がバカ並列(Embarrassingly Parallel)で解けるわけじゃない。一方、旧来のHPCは昔も今も(おそらく)将来もニッチな分野でなくならないだろう。興味があるのは、クラウドとHPCでおそらく独立に発展してきた技術が融合することで、何か新しい技術的発展や応用が生まれてくるんじゃないかということ。

バズワードだけど技術的に新しいことは何もないでしょうと思考停止してしまうのは危険で、たゆまぬ勉強が必要だよなと改めて思った。

P.S. しかしBloggerのエディタは性に合わない。やっぱりはてな日記のようなWiki記法がよいな。