Hadoop入門者向けの注意点とかコツ(1)
修論やっと終わりました…死ぬかと思った。Hadoop MapReduceを利用してちょっとしたことをやったんですが、いろんなところで躓きました。Hadoopには「簡単 大規模 分散処理 なんだかすごい魔法の技術」っていうイメージを抱いていましたが、ぜんぜんそんなことないです。実装すごい大変でした。これからHadoopでMapReduceをやってみようって人のために僕が躓いた所をまとめておきます。
最初に読むべきドキュメント
公式のチュートリアルを読みましょう。バージョンごとにドキュメントが違うので注意してください。英語が苦手だなって人は、日本語のドキュメントを読みましょう(ただし0.20まで)。でもHadoopはトラブルがガンガン起こると思うので、そんなときに英語も頑張って読むぞって人じゃないとHadoopでプログラミングするのは難しいです。
さらに詳しいドキュメントが欲しければオライリーの第二版Hadoop(通称象本)、またはHadoop徹底入門を読みましょう。
- 作者: Tom White,玉川竜司,兼田聖士
- 出版社/メーカー: オライリージャパン
- 発売日: 2011/07/23
- メディア: 大型本
- 購入: 9人 クリック: 182回
- この商品を含むブログ (24件) を見る
- 作者: 太田一樹,下垣徹,山下真一,猿田浩輔,藤井達朗,濱野賢一朗
- 出版社/メーカー: 翔泳社
- 発売日: 2011/01/28
- メディア: 大型本
- 購入: 14人 クリック: 668回
- この商品を含むブログ (43件) を見る
それ以上の中級者だとNTTデータのHadoop報告書、オライリーのHadoop MapReduce デザインパターンですかね。
クラスタの構成
Hadoopをインストールします。OSはUNIX系統が必要です。cygwinを使えばWindowsでもいけるみたいですが、ややこしそうなのでLinuxがいいとおもいます。いろんなサイトをみてるとCentOS(Red Hat系)がよく使われていました。私はOpenSUSE11(Red Hat系?)を使いました。
Hadoopをダウンロードします。Hadoopのソフトウェア群をまとめたHadoopディストリビューションClouderaなんてものがありますが、これを使うとどこに何があるか分かりにくいので初めての人にはおすすめしません。Hadoopの公式からダウンロードしましょう。Hadoopのバージョンは0.23のアルファ版がいいと思います。0.20は安定版ですが古いAPIをメインに利用しているためプログラミングの段階で苦労します。
クラスタ構成時のポイントを書いておきます
- もしEclispeでプログラミングしてテストするって方はHadoopの実行ユーザーをEclipseの実行ユーザーと同じにしておくといいです。
- JDKは最初からインストールされてるOpenJDKではなく本家のものを使います。
- インストールしたらupdate-alternativeまたはalternativeコマンドでjavaのバージョンを切り替えられるようにすると楽です。
- OpenSUSE11ではOpenJDKが入ってる状態で本家のJDKを入れるとパソコンを再起動したときにフリーズしました。これはjexecというのが悪さをしていたようです。本家JDKをインストールした直後に/etc/init.d/rc1〜5で、jexecを起動しないようにしておきましょう。もし起動しなくなったら起動時のjexecでのハングをご覧ください。私はこの方法でもだめだったので、OSインストール時のディスクを使ってレスキューモードでHDD(/dev/sda2)をマウントし、/etc/init.d/rc1〜5をいじりました。
- Hadoop本体を展開
- 一時ファイルの場所を変更する
- 一時ファイルはデフォルトでは/tmp以下に作成されますが、ここに作成したファイルは一定期間後に削除されるので一時ファイルの場所を変更しましょう。
擬似分散や2台以上で動かすのは苦労すると思います。問題が起こった場合、次の確認方法があります。
- ノードの起動時に問題が起こった場合、各ノードのログファイル/opt/hadoop/logs/ディレクトリをみます。
- 起動に成功していればジョブトラッカーやネームノードのWEB UIでタスクトラッカーの台数、データノードの台数が正しいか確認しましょう。きちんと起動しているにもかかわらず台数の表示がおかしいケースもあります。そういう時はサンプルプログラムを一度実行してみてください。
問題が起きやすいのはネットワーク周りとパーミッションです。ネットワーク周りは実験用の環境であれば各ノードのファイアーウォールを切っておくと楽です。パーミッションはローカルファイルシステムのパーミッションだけではなく、HDFSのパーミッションにも問題が起こります。
クラスタ構成を変更した場合はHDFSをフォーマットする必要があります。ここで注意点です。フォーマットする前には全ノードの一時ファイルを削除してから行いましょう。これでよくトラブルが起きます。一時ファイルはデフォルトだと/tmp/hadoop-*のディレクトリに入ってると思います。
クラスタを簡単に管理する
台数が増えるごとに管理が面倒になりますよね。そんなとき自分でスクリプトを書いたり、エイリアスや環境変数を設定すると楽になります。
Hadoopの基本操作
エイリアスでHadoopの記法操作を簡単にします。次の場所やコマンドを、~/.bashrcにaliasで登録しておくと楽です。
h='/opt/hadoop' #Hadoop本体のディレクトリ hadoop_conf='$h/conf' #設定ファイルのディレクトリ hadoop_log='$h/logs' #ログファイルのディレクトリ alias hadoop='$h/bin/hadoop' #Hadoopのバイナリファイル alias h-sample='hadoop $h/bin/hadoop jar $h/hadoop-examples-*.jar pi ' #サンプルの実行
ファイルの同期を簡単にする
クラスタ間でhadoop/confや/etc/hostsなどを同期するのにrsyncを使ったbash、sync.shを書きました。これはマスターノードから利用することを想定しており、指定したファイルを/opt/hadoop/conf/slavesに記述されたホストに同期させます。
#!/bin/sh #引数 # $1 送り元のファイル # $2 送り先のファイル # $3 ターゲットのuser if [ "$1" = "" ] ;then echo "\$1: 送り元を指定してください" exit 1 fi if [ "$2" = "" ] ;then send=$(echo "$1") else send=$(echo "$2") fi if [ "$3" = "" ] ;then user=$(id -un) else user=$(echo "$3") fi while read LINE;do run=$(echo "rsync -avr --delete $1 $user@$LINE:$send") echo $run $run done < "/opt/hadoop/conf/slaves"
このスクリプトの使い方を示します。ディレクトリの場合は後ろに/をつけるのを忘れないで下さい。
sync.sh file_name #ファイルを同期 sync.sh directory_name/ #ディレクトリを同期
これを利用して/etc/hostsや/hadoop/confを同期させるには次のようにします。sync.shは適当なディレクトリに入れておいて、そのディレクトリに対して$script_homeという変数を設定しておきます。
alias sync-conf='$script_home/sync.sh $h/conf/' alias sync-hosts='sudo $script_home/sync.sh /etc/hosts'
このコマンドをaliasに登録しておくと一瞬で/etc/hostsや/hadoop/confを全ノードに同期することができます。
HDFSのフォーマットを簡単に行う
HDFSを正しくフォーマットして使うには全ノードの一時ファイルを削除してからフォーマットする必要があります。これを簡単に行うスクリプトです。
#!/bin/sh remove(){ #$1にはファイル名が入る while read LINE;do echo $LINE removeAtNod $LINE done < "$1" } removeAtNod(){ #$1にはノード名がはいる ssh -n $1 "rm -r /tmp/hadoop-*" } remove "/opt/hadoop/conf/masters" remove "/opt/hadoop/conf/slaves" /opt/hadoop/bin/hadoop namenode -format
以上です
第2回に続きます
追記 2/19 12:21
Cloudera の shiumachi さんからコメントをいただきました。私よりずっと詳しい方ですのでshiumachiさんの意見も参考にしてみてください。/tmpの件については記事の中に入れさせてもらいました。ありがとうございます!