ひしだまの変更履歴

ひしだまHPの更新履歴。
主にTRPGリプレイの元ネタ集、プログラミング技術メモと自作ソフト、好きなゲームや音楽です。

Hadoop Streaming(あるいはC言語 vs Java)

2011-12-26 22:27:10 | PG(分散処理)

Hadoopアドベントカレンダー2011の26日目です。

自分はJavaをそこそこ使ってきたのでHadoopを扱うにもJava APIを使うのが自然な選択でしたが、世間ではHadoop Streamingを使ってJava以外の言語で書くことも多いようです。
という訳で、ちょっとHadoop Streamingを試してみました。


まずはストリーミングってどうやるんだろう?というのをざっと調べる為に「Hadoop Streaming」でググってみたら、さすが色々ありますね~(笑)
Perl・PHP・Python・Ruby、JavaScriptなんてのも!

どうやらhadoop-streaming.jarというJavaプログラムに“各言語で書いたMapper・Reducerプログラム”を引数として渡すようですね。ふむふむ。

と思ってサンプル(おなじみWordCount)を見ていたら、2点ばかり気になることがありました。


1つはReducerでの集計方法で、連想配列(ディクショナリーやマップと呼ばれることもある)を使って単語毎に件数をカウント(保持)していることです。

それって、単語数が多かったらメモリー不足で落ちたりするんじゃないですかね(汗)
(Hadoopは大量データを処理するものですから、そういう所は気にしましょう。メモリー内に入りきるようなデータ量だったら、そもそもHadoopを使う必要ありません)

せっかくキーでソートされて入ってくるんだから、キーブレイク処理にしましょうよ。


もう1つは、カウント時に(Reducerの入力値を使わず)直接1を加算している例が多いことです。
これじゃ何の為にMapperで1を出力しているんだか分かりませんよ^^;

件数カウントをSQLで例えると、通常は「select key, count(*) from t group by key」という風に書くと思いますが、別の方法として「select key, sum(1) from t group by key」と書くことも出来ます。
Mapperで出力している1は、後者の「sum(1)」の1に当たります。

それに、Reducerで入力レコードをカウントする方法でも結果は正しく出ますが、その方法だとCombinerを使ったときにおかしくなりますよね。
と思って実行方法の方を見たら、案の定、Combinerは指定していませんでした。

…というか、どうやら古いバージョンのHadoopでは、CombinerにはJavaのクラスしか指定できなかったようです。それじゃ、ストリーミングのサンプルとしては当然記述しないですよね~^^;
象本によると、Hadoop0.21でCombinerにJavaクラス以外を指定できるようになったようです。また、CDH3も(Hadoop0.20ベースですが)大丈夫でした。
なので、それらのバージョンを使っている人は、ぜひCombinerを指定しましょう。2倍くらい速度が違いますよ!


という訳で、ストリーミングを使ってWordCountを作ってみました。
対象言語は、実行速度が一番速いという噂のC言語(笑)(→ソース

まぁ自分は仮想分散環境しか持っていないので速度を比較するには不適切なんですが、それを踏まえて、結果は、Javaで作ったWordCountとほぼ同じ速度でした。
160MBのファイルをデータノード3台で処理して、Javaが23秒、C言語が25秒という感じです。ちなみにawkだと34秒くらい。

結論。
ストリーミングは標準入出力を使うのでその分は遅いと思いますが、ネイティブな実行ファイルを作るような言語なら、Java APIを使うのとほとんど同じ速度が出るようです。
すごいですね!(どっちが?w)

P.S.
しかし、ストリーミングを使うということは素のMapReduceを書いているのと結局同じなので、そういう意味ではPigHiveを使う方が保守性は良いような?(爆)

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする