Hadoopを試す

Quickstartを参考に単体で使ってみるだけなら、非常に簡単だった。
実験した環境はUbuntu Hardy/x86_64

Javaの環境をセットアップ

 aptitude install java6-sdk
 export JAVA_HOME=/usr/lib/jvm/java-6-sun

JAVA_HOMEの設定はsshで対象ホストに入ってjavaを実行するようなので/etc/profileとかにも書いておく必要がありそう。

sshlocalhostに公開鍵認証で入れるようにしておく

鍵は事前生成していたので

 cat ~/.ssh/id_rsa >>~/.ssh/authorized_keys
 ssh localhost

でそのままログインできる状態になっていることを確認。必要ならばssh-agentなりパスフレーズ無しの鍵などを利用すること。

Hadoopを展開

 tar zxvf hadoop-0.16.3.tar.gz
 cd hadoop-0.16.3

Hadoopの初期設定

dfsもjob管理もlocalhostを参照するように設定

 <configuration>
  <property>
    <name>fs.default.name</name>
    <value>localhost:9000</value>
  </property>
  <property>
    <name>mapred.job.tracker</name>
    <value>localhost:9001</value>
  </property>
  <property>
    <name>dfs.replication</name>
    <value>1</value>
  </property>
</configuration>

新しいdfsを初期化

bin/hadoop namenode -format

名前からするに分散ファイルシステム名前空間を保持するノードに対する初期化処理だろう。

各種daemonを起動

bin/start-all.sh

実体はシェルスクリプトで、dfsとmapredを起動する。前者が分散ファイルシステムのプロセスで、後者がMapReduceの処理実体。

処理対象のファイルをdfs上に置く

bin/hadoop dfs -put conf input

ローカルの”conf”ディレクトリ内のファイルをdfs上のinputというパスに置くという意味。dfs関連のコマンドは

bin/hadoop dfs -ls

のような形でhadoopのサブコマンドとして実行できるlsやらput/get、chownなど一般的なunixのコマンド相当の物が揃っている。

処理を実行する

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

意味としては、配布物に含まれるhadoop-0.16.3-examples.jarというjarファイルを指定し、その中のgrepコマンドを実行している。それ以降のパラメータはgrepへの引数。入力元と出力先とパターン。
実行すると以下のような処理経過が表示されて、結果はdfsに置かれる。

08/05/03 07:49:14 INFO mapred.FileInputFormat: Total input paths to process : 9
08/05/03 07:49:15 INFO mapred.JobClient: Running job: job_200805030517_0011
08/05/03 07:49:16 INFO mapred.JobClient:  map 0% reduce 0%
08/05/03 07:49:22 INFO mapred.JobClient:  map 20% reduce 0%
08/05/03 07:49:24 INFO mapred.JobClient:  map 40% reduce 0%
08/05/03 07:49:26 INFO mapred.JobClient:  map 60% reduce 0%
08/05/03 07:49:28 INFO mapred.JobClient:  map 80% reduce 0%
08/05/03 07:49:30 INFO mapred.JobClient:  map 100% reduce 0%
08/05/03 07:49:40 INFO mapred.JobClient:  map 100% reduce 100%
08/05/03 07:49:41 INFO mapred.JobClient: Job complete: job_200805030517_0011
08/05/03 07:49:41 INFO mapred.JobClient: Counters: 12
08/05/03 07:49:41 INFO mapred.JobClient:   Job Counters
08/05/03 07:49:41 INFO mapred.JobClient:     Launched map tasks=10
08/05/03 07:49:41 INFO mapred.JobClient:     Launched reduce tasks=1
08/05/03 07:49:41 INFO mapred.JobClient:     Data-local map tasks=10
08/05/03 07:49:41 INFO mapred.JobClient:   Map-Reduce Framework
08/05/03 07:49:41 INFO mapred.JobClient:     Map input records=1338
08/05/03 07:49:41 INFO mapred.JobClient:     Map output records=48
08/05/03 07:49:41 INFO mapred.JobClient:     Map input bytes=40695
08/05/03 07:49:41 INFO mapred.JobClient:     Map output bytes=1290
08/05/03 07:49:41 INFO mapred.JobClient:     Combine input records=48
08/05/03 07:49:41 INFO mapred.JobClient:     Combine output records=44
08/05/03 07:49:41 INFO mapred.JobClient:     Reduce input groups=43
08/05/03 07:49:41 INFO mapred.JobClient:     Reduce input records=44
08/05/03 07:49:41 INFO mapred.JobClient:     Reduce output records=43
08/05/03 07:49:42 INFO mapred.FileInputFormat: Total input paths to process : 1
08/05/03 07:49:43 INFO mapred.JobClient: Running job: job_200805030517_0012
08/05/03 07:49:44 INFO mapred.JobClient:  map 0% reduce 0%
08/05/03 07:49:48 INFO mapred.JobClient:  map 100% reduce 0%
08/05/03 07:49:53 INFO mapred.JobClient:  map 100% reduce 100%
08/05/03 07:49:54 INFO mapred.JobClient: Job complete: job_200805030517_0012
08/05/03 07:49:54 INFO mapred.JobClient: Counters: 12
08/05/03 07:49:54 INFO mapred.JobClient:   Job Counters
08/05/03 07:49:54 INFO mapred.JobClient:     Launched map tasks=1
08/05/03 07:49:54 INFO mapred.JobClient:     Launched reduce tasks=1
08/05/03 07:49:54 INFO mapred.JobClient:     Data-local map tasks=1
08/05/03 07:49:54 INFO mapred.JobClient:   Map-Reduce Framework
08/05/03 07:49:54 INFO mapred.JobClient:     Map input records=43
08/05/03 07:49:54 INFO mapred.JobClient:     Map output records=43
08/05/03 07:49:54 INFO mapred.JobClient:     Map input bytes=1542
08/05/03 07:49:54 INFO mapred.JobClient:     Map output bytes=1198
08/05/03 07:49:54 INFO mapred.JobClient:     Combine input records=0
08/05/03 07:49:54 INFO mapred.JobClient:     Combine output records=0
08/05/03 07:49:54 INFO mapred.JobClient:     Reduce input groups=3
08/05/03 07:49:54 INFO mapred.JobClient:     Reduce input records=43
08/05/03 07:49:54 INFO mapred.JobClient:     Reduce output records=43

処理内容は入力ファイルをパターンマッチさせてその結果を集計するだけなので、入力ファイルの規模にしては分散のオーバーヘッドが大きいため非常に時間がかかっている。

結果の取得

bin/hadoop dfs -get output output

とすることで、ローカルのファイルシステムに取ってくることができる。

bin/hadoop dfs -get output output 

などとして、直接参照することも可能

まとめ

  • 1ノードで上げてみるだけなら非常に簡単
  • 処理の流れはdfsに対象ファイルを置く、MapReduceで書かれた処理を実行、結果をdfsから取得という感じ
  • dfsを扱うコマンドは一通りunix likeなものが揃っているので、aliasを書くなりすればそれなりに使えそう。fuseでmountできればもっと便利なのだけど
  • 少ないノード数で小さい対象を扱う分にはオーバーヘッドがかなり大きい
  • 多数のノードを扱うにはちょっと煩雑
  • 処理内容は基本的にJavaで書くが、JVMで動く言語なら大丈夫
  • Jythonで書かれたwordcountのサンプルがあるが、これがかなり簡潔に記述されていて素敵

つーことで、これからJython本を買ってきます

Jythonプログラミング

Jythonプログラミング