概要

ここでは擬似分散(Pseudo-Distributed)モードでHadoopをインストールします。ClouderaのCDH3を利用しています。

@CretedDate 2011/10/23
@Versions Hadoop0.20, Ubuntu10.04, CDH3

擬似分散モードについて

前項で説明したように、HadoopはNameNode(HDFS親)DataNode(HDFS子)JobTracker(MapReduce親)TaskTracker(MapReduce子)という親子関係で成り立っています。

擬似分散モードはこれら4つの機能を1台のマシンで動作させます。

つまり自分で「分散して処理をしろ」と命令し、自分で「はい、わかりました」と言って実行するするという、寂しい一人芝居をするモードです。

寂しくはありますが、NameNodeやDataNodeなどの機能をインストールして動かすことになるので、1台しかパソコンがない場合でもなんとなくHadoopの雰囲気を味わえます。

Clouderaについて

今回はClouderaが出しているCDH3(Cloudera Distribution including Apache Hadoop v3)を利用しています。

CDHは名前の通り、Cloudera社が出しているHadoopのディストリビューションです。

apt-getyumでHadoopをインストールできたり、インストール時に行う必要がある面倒な作業の一部を肩代わりしてくれたりします。

Cloudera社はHadoopの開発者が多数在籍しており、Hadoop関連のソフトウェアをオープンソース(Hadoopと同じApacheライセンス)で提供してくれています。Scalaに対するTypeSafeみたいな会社と言えば一部の人には分かりやすいでしょうか。

ドキュメントとかもけっこう公開してくれています。
Cloudera : http://www.cloudera.com/

現在提供されているディストリビューションはHadoop0.20ベースになっていますが、一部0.21の機能も組み込まれているそうです。

下準備

Hadoopのインストールを始める前に、sshとかrsyncとかそれっぽいものを入れておきます。

// とりあえずsshは入れる
$ sudo apt-get install ssh

// rsyncも入れる
$ sudo apt-get install rsync

// ntpも入れとく
$ sudo apt-get install ntp

// curlも入れよう
$ sudo apt-get install curl

// OpenJDKではなくて故SunのJDKを入れる
$ sudo aptitude install python-software-properties
// 本例はUbuntu10.04なのでlucid partner
$ sudo add-apt-repository 'deb http://archive.canonical.com/ lucid partner'
$ sudo apt-get update
$ sudo apt-get install sun-java6-jdk

Hadoopのインストール

次にHadoopの擬似分散モードを入れます。

単純にapt-getと言うだけでは入らないので、レポジトリを追加したりしています。

// source.list.d配下にファイルを追加
$ sudo vi /etc/apt/sources.list.d/cloudera.list

deb http://archive.cloudera.com/debian lucid-cdh3 contrib
deb-src http://archive.cloudera.com/debian lucid-cdh3 contrib

$ curl -s http://archive.cloudera.com/debian/archive.key | sudo apt-key add -
$ sudo apt-get update
$ sudo apt-get install hadoop-0.20-conf-pseudo

こんな感じで実行すると、以下のようなメッセージが出てきます。

以下のパッケージが新たにインストールされます:
  hadoop-0.20 hadoop-0.20-conf-pseudo hadoop-0.20-datanode hadoop-0.20-jobtracker hadoop-0.20-namenode hadoop-0.20-native
  hadoop-0.20-secondarynamenode hadoop-0.20-tasktracker liblzo2-2

以下のものがインストールされるようです。

hadoop-0.20Hadoopの本体
hadoop-0.20-conf-pseudo擬似分散モードの設定ファイル
hadoop-0.20-namenodeNameNode
hadoop-0.20-datanodeDataNode
hadoop-0.20-jobtrackerJobTracker
hadoop-0.20-tasktrackerTaskTracker
hadoop-0.20-secondarynamenodeSecondaryNameNode
hadoop-0.20-native圧縮関連のnativeライブラリ
liblzo2-2LZO圧縮機能

Hadoop本体と設定ファイル、それからお馴染みのNameNodeDataNodeJobTrackerTaskTrackerが入ります。

SecondaryNameNodeは名前の通りNameNodeのサブ的な機能です。とりあえずはいなくても動くのでここでは説明を割愛。

これらは/etc/rc.dにも登録されます。ということで再起動するとNameNodeやDataNodeは自動的に立ち上がります。

また、/etc/init.dの中を覗くと以下のファイルが出来上がっています。

hadoop-0.20-namenode
hadoop-0.20-datanode
hadoop-0.20-jobtracker
hadoop-0.20-tasktracker
hadoop-0.20-secondarynamenode

ということでservice hadoop-0.20-namenode restart | start | stopのような形でnamenodeやdatanodeを起動したり終了したりできます。

Hadoopを導入する時に割と用意が面倒な設定ファイルたちも用意してくれています。/etc/hadoop-0.20/conf.pseudoの配下がそれです。

HDFSの操作をする時に利用するhdfsという名前のユーザと、MapReduce用にmapredというユーザも作成されています。

$ cat /etc/passwd | grep hdfs
$ cat /etc/passwd | grep mapred

要約すると、CDH3をインストールすると、いろんなものが入ったりいろんなものが作られたりします。

分散モードを立ち上げる

とりあえず再起動するとNameNodeやDataNodeは立ち上がります。

立ち上がっているかどうかはstatusでrunningと出ればOKです。

$ service hadoop-0.20-namenode status
hadoop-0.20-namenode is running

$ service hadoop-0.20-datanode status
hadoop-0.20-datanode is running

手動で立ち上げる場合はserviceでstartします。

$ service hadoop-0.20-namenode start
$ service hadoop-0.20-datanode start
$ service hadoop-0.20-jobtracker start
$ service hadoop-0.20-tasktracker start

完全分散モードだとstartした後、立ち上がったフリをして即効で落ちていることもけっこうある。そんな時は「/usr/lib/hadoop-0.20/logs」配下の対応するログを見ます。

$ view /usr/lib/hadoop-0.20/logs/hadoop-hadoop-namenode-*.log

namenode、datanode、jobtracker、tasktrackerがそれぞれにログを吐いてます。たいていのエラー原因はここを見れば分かります。

NameNodeとJobTrackerの状態は以下のアドレスで確認できます(それぞれNameNode、TaskTrackerが動いているマシンのlocalhost)。

NameNode: http://localhost:50070/

JobTracker: http://localhost:50030/

上記URLが表示されればとりあえずNameNodeとJobTrackerは無事起動しているはずです。

HDFSを使ってみる

さっそくHDFSを使ってみましょう。HDFSは以下のようにhadoopコマンドにLinuxのコマンドっぽい引数を付けてあげると実行できます。

$ hadoop fs -ls
ls: Cannot access .: No such file or directory.

まず、試しにデータを1つHDFS上に置いてみましょう。データはputコマンドで置けます。

// ディレクトリを作る
$ hadoop fs -mkdir /user/yourname

// HDFS上に置くファイルを作る
$ echo test > test.txt

// putしてみる
$ hadoop fs -put test.txt /user/yourname

// 置けたことを確認
$ hadoop fs -ls /user/yourname
Found 1 items
-rw-r--r--   1 yourname supergroup          5 2011-10-27 23:47 /user/yourname/test.txt

// catしてみる
$ hadoop fs -cat /user/yourname/test.txt
test

// HDFS上からローカルにファイルを移す
$ hadoop fs -get /user/yourname/test.txt foo.txt

// ディレクトリを削除する
$ hadoop fs -rmr

他にもたくさんコマンドはあります。詳細はこちらにまとめました。

触ってみると分かりますが、動作はとても重いです。分散したりネットワーク上で飛ばしたりいろいろやってるので仕方ないことですが。

複数のハードディスクに登録してみる

現状の擬似分散モードではHDD1台にデータが登録されていますが、設定を書き換えればブロックごとに複数のマシン、複数のHDDに分散してデータを登録するようになります。

我が家のパソコンはHDDを4台積んでいるので、1台のパソコンでも分散のメリットを味わえます。多分、eSATAやUSB3.0のHDDとかなら外部接続でもメリットを享受できるんじゃないでしょうか。

試しにやってみましょう。HDFSの設定は「hdfs-site.xml」というファイルに記述します。

// /mnt/sda2,sdb1,sdc1,sdd1というパスがmountされてるとして
// とりあえずhdfsユーザ用の
$ sudo mkdir /mnt/sda2/hdfs
$ sudo mkdir /mnt/sdb1/hdfs
$ sudo mkdir /mnt/sdc1/hdfs
$ sudo mkdir /mnt/sdd1/hdfs
$ sudo chown hdfs:hdfs /mnt/sda2/hdfs
$ sudo chown hdfs:hdfs /mnt/sdb1/hdfs
$ sudo chown hdfs:hdfs /mnt/sdc1/hdfs
$ sudo chown hdfs:hdfs /mnt/sdd1/hdfs

// hdfs-site.xmlを編集
$ sudo vi /etc/hadoop-0.20/conf/hdfs-site.xml

// dfs.data.dirというnameのpropertyを追加して、カンマ区切りでパスを入れる
  <property>
    <name>dfs.data.dir</name>
    <value>/mnt/sdb1/hdfs,/mnt/sdc1/hdfs,/mnt/sdd1/hdfs</value>
  </property>

// datanodeを再起動してフォーマット
$ sudo service hadoop-0.20-datanode restart
$ sudo -u hdfs hadoop datanode format

これでhttp://localhost:50070/を見ると、Configured Capacityの容量が増えているはず。

3TBを4台繋げば12TBのデータを持てるHDFSの出来上がり。但し擬似分散モードはレプリカの設定が1(複製は持たない)になっているので、1台でもHDDが死ねば全データが失われる素敵な状態ではありますが。

長時間使って遊ぶ場合はdfs.replicationを2くらいにしておくと良いかもしれない。

MapReduceしてみる

以下のパスにMapReduceで処理を行うサンプルjarが用意されている。

/usr/lib/hadoop-0.20/hadoop-examples.jar

このjarにはいろんな機能が入っていて、grep、sort、join、単語数のカウント、円周率の計算なんかが入っている。ソースを落としてくればサンプルコードとしても役立つ。

ソースはこの辺から落とす
http://hadoop.apache.org/common/releases.html#Download

hadoop-0.20.205.0.tar.gzを落とした場合、src/examples/org/apache/hadoop/examples 配下にソースがいる。

注意点として、mapredパッケージを使っている機能とmapreduceパッケージを使っている機能の2種類がいる。mapredが古いAPIでmapreduceが新しいAPIで混在している。mapredにはあるけどmapreduceにはない(0.21には入ってる)ような機能もあるので扱いが難しい。

試しに単語数のカウント機能(英語用だから形態素解析とかは無理)を使ってみる。

// 適当な英文を出力する
$ vi i_have_a_dream.txt

I have a dream that one day this nation will rise up and live out the true meaning of its creed: We hold these truths to be self-evident: that all men are created equal.

// hdfsユーザになってhomeディレクトリを作っておく
$ sudo su hdfs
$ hadoop dfs -mkdir /user/hdfs

// putする
$ hadoop dfs -put i_have_a_dream.txt .

// word countを実行する
$ hadoop jar /usr/lib/hadoop-0.20/hadoop-examples.jar wordcount i_have_a_dream.txt outdir

これを実行すると、引数で指定したoutdirというディレクトリの中に結果が出力されます。

$ hadoop dfs -ls outdir

// 結果を見てみる
$ hadoop dfs -cat outdir/part-r-00000

上記のコマンドを実行すると、なにやら単語の一覧とカウントがタブ区切りで出力されます。

まとめ

こんな感じで擬似分散モードは実際に利用するであろう環境に非常に近いものであり、設定ファイルを書き換えて反映させれば動作が変わったりもします。

1台のマシンでそこそこにHadoopの妙技を味わいたいという場合には、なかなかに便利です。

ただ、実際に完全分散モードを利用しないとHadoopの感動は味わえないので、安物でもいいのでなんとかパソコンを3台くらい揃えて分散させてみた方が世界が開けて見えたりすることもあると思います。