Hadoopを用いたクラスタコンピューティング環境の構築

 ペタバイト規模のデータを格納させる分散コンピューティング用プラットフォームを探しているのであれば、そのフレームワークとして Hadoop の使用を検討すべきだろう。HadoopはJavaベースで作成されているため、Linux、Windows、Solaris、BSD、Mac OS Xにて使用できる。こうしたHadoopを実際に採用している組織に共通するのは、安価(特殊なハードウェアが不要)かつ効率的でスケーラビリティと信頼性を兼ね備えたプラットフォームによる、膨大な量のデータ処理を必要としているという点だ。

 Hadoopでは、こうした膨大な量のデータを格納するために、Hadoop Distributed File System(HDFS)を採用している。実際、HDFSのマスタ/スレーブアーキテクチャは、Hadoopのクラスタ機能の中核を成している。ここでサポートされているのは、ファイルシステムのメタデータ管理用マスタサーバとして機能する1つのNameNodeおよび、実際のデータ群を格納する多数のDataNodesという基本構成だ。

 ただしNameNodeは単一点障害(single point of failure)となる危険性があるため、HadoopではSecondary NameNodeを用意することで、名前空間の定期チェックをさせると同時に、NameNodeに保持させるHDFSの変更ログファイルを一定サイズ以下にするようにしている。こうしたHDFSのアーキテクチャについては、ダイヤグラムを用いた解説ドキュメントが公開されており、また「HDFS User Guide」というユーザの視点に立った包括的なHDFSの導入ガイドも参考になるだろう。

 Hadoopにおけるデータ分散処理のベースとなっているのは、Googleにより提唱されたMapReduceというプログラミングモデルだ。このモデルをHadoopの場合は、各ノードにおけるJobTrackerプロセスが、クラスタのジョブスケジューラおよびアロケータとして機能し、個々のクラスタノードにおけるTaskTrackerへのジョブ割り当てを行うという方式にて実装している。つまりJobTrackerとTaskTrackerの関係は、前者がMapReduceマスタで、後者がMapReduceスレーブという位置付けと見ればいいだろう。

 Hadoopクラスタの機能ユニットである、NameNode、DataNodes、JobTracker、TaskTrackerは、いずれもデーモンとして実装される。そしてすべてのノードには、クラスタの状態をチェックするためのWebサーバが組み込まれるようになっている。NameNodeにおけるこうしたWebサーバの役割は、DataNodesのステータス情報をレポートすることであり、これによって、ライブおよびデッド状態のノード、分散ファイルシステムの容量など、様々な情報を確認できる。TaskTrackerおよびその上で実行中のタスクに関するステータス情報は、JobTrackerにて動作するWebサーバにより監視できる。

 本来Hadoopは、Nutchプロジェクト用のインフラストラクチャとして作成されたもので、これはインターネット上のWebページ群を巡回して検索エンジン用のインデックスを構築する、クローラとしての用途が意図されていた。このような背景を有しているHadoopにとって、膨大な量のデータを対象に同様のプロセスを実施するというタスクは、非常に親和性の高い分野なのである。

 Hadoopは、3つの動作モードにて実行させることができ、その1つであるデフォルト状態のHadoopでは、分散型モデルではなく単一のJavaプロセスとして動作するように設定されている。これは実用には適さない設定ではあるが、複数のコンピュータを準備する必要がないため、Hadoopの操作法を学習するのには役立つはずだ。またこれと同様の目的で、Hadoopのデーモン群を1つのノード内で動作させつつ、Javaプロセスとしては各デーモンが個別に動作するという、疑似分散モードも用意されている。最後に残された完全分散モードの場合、当然ながらHadoopを実行するノード群では、NameNode、JobTracker、DataNodes、TaskTrackerを実際に分散させた形で使用することになる。なお、こうした分散モードによるHadoopのセットアップには、最低3つのノードが必要だ。

Hadoopクラスタの完全分散モードでのセットアップ

 今回私はHadoopを試用するにあたって、Debian "Lenny"ベータ2、Sun JDK 1.6Hadoop 0.17.2.1をインストールした3台の標準的なLinuxマシンを用いて、3ノードクラスタをセットアップした。その他に必要なソフトウェアとしては、SSHクライアントおよびサーバを用意して個々のノードにて実行させなくてはならない。

 まず最初に、gunzipを使ってHadoopのtarボールを展開するが、書き込み権限さえ有していれば、展開先は任意のディレクトリで構わない。ここでのディストリビューションのルートは、HADOOP_HOMEとして参照される。通常、クラスタ上で使われるすべてのコンピュータは、同一のHADOOP_HOMEパスを共有することになるので、例えば.bashrcなどのログインスクリプトにHADOOP_HOMEをエクスポートしておくと便利なはずだ。

 Hadoopの設定情報は、HADOOP_HOME/conf/ディレクトリに格納された2つの設定ファイルによって管理される。このうちhadoop-default.xmlは、デフォルト設定を保持する読み取り専用のファイルであり、一方のhadoop-site.xmlは、ノード固有の設定情報を保持するという役割分担になっている。後者のファイルに具体的に何が記載されるかは、クラスタ内で果たすべきノードの役割によって変わってくるが、いずれにせよここに指定されたプロパティ設定は、デフォルト設定用ファイルでの指定よりも優先して適用される。なお配布用のtarボールには、空欄状態のdefault-site.xmlが用意されているので、これを基に各自のニーズに則した変更を施せばいいだろう。

 同様に重要なファイルがconf/slavesである。このファイルはJobTrackerにて、TaskTrackerデーモンを始動させる必要のあるホストの一覧として機能する。同じくNameNodeでは、DataNodesデーモンを始動させる必要のあるホストの一覧として機能する。ただしこのファイルの管理作業は、多数のノードを扱うようにスケーリングさせた場合であっても、すべて手作業で行わなくてはならない。

 その他、JAVA_HOMEを始めログやプロセスID群の保管先といった、各種の設定オプションを格納するconf/chadoop-env.shも重要なファイルである。

 今回用いた試験用のセットアップでは、NameNodeおよびJobTrackerを1つ目と2つ目のノードに個別にインストールし、DataNodesおよびTaskTrackerは、まとめて3つ目のノードにインストールした。最初の2つのノードに置かれたconf/slavesファイルには、3番目のノードのIPアドレスが登録してあり、これら4つのデーモンが使用するconf/hadoop-site.xmlファイルは共通化してある(サンプルはここからダウンロード可能)。conf/hadoop-site.xmlには各種のプロパティ設定を施すことになるが、その詳細はオンラインドキュメントにまとめて解説されているので、そちらを参照して頂きたい。

 その他に必要となるのが、ノード間におけるpassphraseless SSHのセットアップである。またノード参照をホスト名で行う場合は、各ノードの/etc/hostsファイルに対して、用いるホスト名とIPアドレスとのマッピング情報に関する設定をしなくてはならない。

Hadoopのスタートアップ手順

 Hadoopクラスタを使用するには、HDFSおよびMapReduceを両方とも起動しておく必要がある。またそのための準備としては、NameNodeのHADOOP_HOMEに移動し、bin/hadoop namenode -formatといったコマンドを用いて、新規の分散ファイルシステムのフォーマットを行っておかなくてはならない。この処理の完了後にHDFSを起動させるが、それにはターゲットとなるNameNodeにて下記のコマンドを実行すればいい。

$ bin/start-dfs.sh

starting namenode, logging to /home/amit/hadoop/hadoop-0.17.2.1/bin/../logs/hadoop-amit-namenode-lenny-sandbox.out
10.10.10.3: starting datanode, logging to /home/amit/hadoop/hadoop-0.17.2.1/bin/../logs/hadoop-amit-datanode-lenny-2.out
localhost: starting secondarynamenode, logging to /home/amit/hadoop/hadoop-0.17.2.1/bin/../logs/hadoop-amit-secondarynamenode-lenny-sandbox.out

 このbin/start-dfs.shスクリプトは、NameNodeのconf/slavesファイルを参照して、そこに一覧された全スレーブにおいてDataNodesデーモンを始動させるという機能も有している。

 次に行うMapReduceの始動では、ターゲットとなるNameNodeにて下記のコマンドを実行する。

$ bin/start-mapred.sh

starting jobtracker, logging to /home/amit/hadoop/hadoop-0.17.2.1/bin/../logs/hadoop-amit-jobtracker-lenny-1.out
10.10.10.3: starting tasktracker, logging to /home/amit/hadoop/hadoop-0.17.2.1/bin/../logs/hadoop-amit-tasktracker-lenny-2.out
bin/start-mapred.sh
starting jobtracker, logging to /home/amit/hadoop/hadoop-0.17.2.1/bin/../logs/hadoop-amit-jobtracker-lenny-1.out
10.10.10.3: starting tasktracker, logging to /home/amit/hadoop/hadoop-0.17.2.1/bin/../logs/hadoop-amit-tasktracker-lenny-2.out

 このbin/start-mapred.shスクリプトも、当該JobTrackerのconf/slavesファイルを参照して、そこに一覧された全スレーブにおいてTaskTrackerデーモンを始動させるという機能を有している。

 次に、クラスタが正常に起動しているかのクロスチェックとして、各ノードにて実行されているプロセスを、jpsを用いて確認しておく。例えばこの試用例のような3ノードクラスタの場合、NameNodeの一覧中にはJpsとNameNodeに加えて、SecondaryNameNodeのプロセスが示されているはずだ。同じくJobTrackerについては、JpsとJobTrackerが一覧されているかを確認し、TaskTracker/DataNodeについては、Jps、DataNodes、TaskTrackerが一覧されているかを確認する。

MapReduceジョブ群の実行

 Hadoopクラスタの起動に成功したら、hadoop-0.17.2.1-examples.jarにバンドルされているサンプル用のMapReduce Javaクラスファイル群の1つを実行してみることで、実際に動作する様子を確認することができる。ここでは、テキストファイル中から指定の文字列とマッチする部分を抽出して、該当箇所の数をカウントするGrepというサンプルを試してみよう(紛らわしいが、このサンプル名は先頭を大文字とするのが正式である)。

 この場合、Grep用のインプットセットを最初に準備しておかなくてはならない。ここでの実行例では、conf/ディレクトリに格納したファイル群をGrepにインプットさせるようにした。Grepを実行すると、正規表現にて指定された検索文字列に対し、それにマッチする部分が抽出され、処理が正常に終了したかのチェックが行われる。この場合のパラメータとしては、インプットとアウトプット(出力データを格納させるDFSのディレクトリ)および、検索対象とする正規表現の文字列を指定しなければならない。

bin/hadoop dfs -copyFromLocal conf input

bin/hadoop dfs -ls

Found 1 items
/user/amit/input	<dir>		2008-10-12 00:38	rwxr-xr-x	amit	supergroup

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

 処理終了後の結果については、ローカルのファイルシステムにコピーされた出力結果を使って、意図どおりの処理が行われていたかを確認して頂きたい。なお、HadoopのデータはDFS上のブロック群として格納されるため、通常使われるUnixの:/p>コマンドでは表示できないようになっている。

bin/hadoop dfs -get grep-output output
cd output
ls
3       dfs.
3       dfs.class
3       dfs.replication
2       dfs.period
1       dfs.max.objects
...

 HadoopのHDFSおよびJobTrackerのモニタリングについては、バンドルされているWebアプリケーションを介して行うようになっている。HDFSの管理パネルを呼び出すには「http://NameNode IPaddr:5070」を入力すればよく(スクリーンショットを参照)、同じく、現在実行中のジョブおよび過去に実行または失敗したジョブの履歴は「http://JobTracker IPaddr:50030」によりアクセスできる(スクリーンショットを参照)。

 クラスタで行うべき作業の終了後、HDFSを停止させるには、NameNodeにてbin/stop-dfs.shコマンドを実行し、MapReduceを停止させるには、JobTrackerにてbin/stop-mapred.shコマンドを実行すればいい。

 Hadoopのスケーラビリティに関しては、4,000ノードをサポートさせたという事例が知られている。初心者の場合、最初は小規模なクラスタから始めるのが常道だが、その後は必要に応じて拡大させていけばいいだろう。後日、実際に導入した成功事例などを紹介して頂ければ幸いである。

Amit Kumar Sahaは、コンピュータサイエンスおよびエンジニアリングを専行するインド出身の学生で、Linuxやオープンソースソフトウェアを始め、主として初心者を対象としたテクニカル関連の記事を執筆する傍ら、オープンソース関連のドキュメント作成プロジェクトにも貢献者として参加している。

Linux.com 原文(2008年10月22日)