HbaseとPigで遊んでみる。その1
そんなわけでもうそろそろ6月ですが、3月のに行ったインターンで学んだこととか思い出すためにHadoopで遊んでみました。
方針的にはHBaseを中心に、適当にTwitter検索的なものを作ってみたり、あとはPigとかいじれればいいなぁ、と考えてます。
あと、基本的には「Hadoop徹底入門」をベースに経験をプラス、といったところです。
あまり有用な情報があるかは分かりませんが、メモ程度に。
兎にも角にもとりあえず準備から。
準備
手頃なマシンもないし、最初はEC2とか使ってみようかなー、とか思ったのですが、諸般の都合でVMWare上でやってます。
OSは適当にCentOS。Gentooとかも考えたんだけど、めんどそうなので一番簡単そうなせんとくんで。
HadoopはClouderaのをyumで。一番簡単そうn(ry
ついでにいえば、一番簡単そうな疑似分散モードで遊ぼうと思ってます。
気が向いたら、というか、マシンの都合がついたら完全分散とか試してみるかも。
なにはなくともOSのインストール。
デスクトップ環境はいらないなー、と思ってoffにして、あとはデフォでいいかなー、とか思ったらCentOSくんってデフォではgcc入ってないのね。
インストール時に指定できるのかしらん?次回機会あったら見てみよう。
で、Hadoopを入れる前にすこしだけ準備。
とりあえず、screenだとかvimだとかそういう個人的に必要な開発環境一式はてきとうにそろえて、それに加えて必要なのがJDKのインストール。
HadoopはJavaで実装されているのでJavaが必要なのですが、yumで入れられるopenjdkだと不具合がある。
ので、SUNっていうかORACLEから、JDKを落としてきて入れます。
http://java.sun.com/javase/ja/6/download.html
のJDKから、Linux x64えらんで、rpmのついている方をダウンロードしてsudoで実行でok。
sudo sh jre-6u25-linux-x64-rpm.bin
あと、HBaseで遊ぶ時便利なhbase shellがirbで動いているので、Rubyのセットアップすると便利かな、とか思ったけど、jrubyなので微妙に別物。
がんばってhbase shellでrubygemsをrequireできないか格闘してみたけど、なかなか難しそう。
まぁ、最悪.irbrcに
IRB.conf[:SAVE_HISTORY] = 100
を書いておけば困らないかと。
あとHadoopとは別に、今回twitterからデータを引っ張ってこようと思っているので、やっぱりRubyのセットアップが必要。
OAuthとかRubyでライブラリに任せてちゃちゃっと済ませるのが一番ですよねー。
せんとくんのRubyは1.8.5というなかなかにアレ気なRubyなので、ソースを落としてきて./configure && make && make install。
CentOS的にはcheckinstall(?)とかいうのを使ってRPM化してインストール、とかの方がいいのかな?という雰囲気なのですが、まぁ、普通にmake installして大丈夫でしょう。
そういやpocoとかいうmake installしたファイルを管理してくれるソフトがあった気がするけど、アレって便利なんかなぁ? TODO:あとで試す。
ついでにrubygemsも落としてきてmake install!!
gemでoauthとその依存をinstall。
あとutility_beltとかwirbleも入れておくと便利かも(hbase shellでは使えないけど……)。
履歴や補完、カラーリングとかやってくれます。
全機能はあまり把握してないケドいろいろ便利らしい。
あと「Preferred Research」で太田さんも述べられています*1が時刻合わせをしておくといいかも。
インターン中になぜか一台だけ一日ほど未来に生きている子がいて、それが直接的な原因かはわからないけれど、びみょーにいやーな感じになったので……。
ntpを適当にyumって、chkconfigでntpdをonにすればok。
あと大規模運用を安定して、という場合には太田さんの記事を参考にカーネルパラメータ等々をいじるといいと思います。
遊ぶぶんにはいらないとは思います。
Hadoopのインストール。
前述の通り、Clouderaからyumで入れる方針で。
とりあえず、Clouderaからredhat系のrepoファイルを落としてきて、yumのreposに追加します。
wget http://archive.cloudera.com/redhat/cdh/cloudera-cdh3.repo
sudo mv cloudera-cdh3.repo /etc/yum.repos.d/
yum search hadoop
これでhadoop関係のプロダクトがsearchできるようになったはず。
今回はHBaseとPigで遊ぼうかと思っているので、先に必要そうなパッケージをまとめてinstallしちゃいます。
sudo yum install hadoop-0.20{,-conf-pseudo,-datanode,-namenode,-jobtracker,-tasktracker,-secondarynamenode} hadoop-hbase{,-master,-regionserver,-thrift} hadoop-pig hadoop-zookeeper{,-server}
bash方言なんで中括弧は適当に処理してくだしあ。
hadoop-0.20* は hadoop-0.20-conf-pseudo の依存で落ちてくるそうですが、適当に。
HBaseについては他のサイトで調べてもらうことにして、今回はこのpseudo、疑似分散モードで行きます。
conf-pseudoをいれると疑似分散モードで最低限動く設定がインストールされます。
で、本来なら設定をコピーするなりしてひな形作って編集して、alternativesでinstallして優先度を確かめて、という作業が必要なのですが、動くので放置。
mapred.system.dirとかぐらいはもう少しわかりやすい名前にするのがいいのでしょうけど。
ちなみに、インストールされるファイルは「rpm -q -l <パッケージ名>」で確認できます。
ファイルのインストールの他にユーザも追加されて、cdh3ではMapReduce用のmapredユーザとHDFSをいじるhdfsユーザが追加されるようです。
$ id mapred uid=101(mapred) gid=105(mapred) 所属グループ=105(mapred),103(hadoop) context=user_u:system_r:unconfined_t $ id hdfs uid=102(hdfs) gid=104(hdfs) 所属グループ=104(hdfs),103(hadoop) context=user_u:system_r:unconfined_t
が、なんか使い分けは適当でもなんとかはなります。はい。
「Hadoop徹底入門」ではディレクトの所有者だとか、パーミッションとか結構細かく書いてあるのですが、ディレクトリを作らずに起動すると自動で作ってくれる場合が多いようなので、下手に自分で作って謎のエラーに悩まされるぐらいなら放置で。
あと、chkconfig --listしてみると、どうやらデフォルトで起動する設定になっている模様。
遊ぶだけなら毎回起動する必要はないし、自動起動はoffにしてもよいかも。
どのディレクトリがどのユーザで、とかは、なんどかHadoopのインストールを繰り返すとそのうち覚えるかと思います。
インターンからまる2ヶ月たった今現在ではすっかり忘れてますが……。
/etc/hadoop-0.20/conf/ 以下のcore-site.xmlやhdfs-site.xml、mapred-site.xmlあたりが編集するファイル。
slaveやmasterは自動起動やらなんやらで使うものらしいので、その辺を使わないなら完全分散モードでもいじる必要はないです。
HDFSの起動
そんなわけで、pseudoそのままで動いてしまうので、動かしてみましょう。
一応、alternativesを使って設定を確認
$ /usr/sbin/alternatives --display hadoop-0.20-conf hadoop-0.20-conf -ステータスは自動です。 リンクは現在 /etc/hadoop-0.20/conf.pseudo を指しています。 /etc/hadoop-0.20/conf.empty - 優先項目 10 /etc/hadoop-0.20/conf.pseudo - 優先項目 30 現在の「最適」バージョンは /etc/hadoop-0.20/conf.pseudo です。
pseudoが「最適(best!)」になっていることを確認したら、とりあえずさくっとnamenodeをフォーマットします。
$ sudo -u hdfs hadoop namenode -format 11/05/30 03:01:12 INFO namenode.NameNode: STARTUP_MSG: /************************************************************ STARTUP_MSG: Starting NameNode STARTUP_MSG: host = vCentOS/127.0.0.1 STARTUP_MSG: args = [-format] STARTUP_MSG: version = 0.20.2-cdh3u0 STARTUP_MSG: build = -r 81256ad0f2e4ab2bd34b04f53d25a6c23686dd14; compiled by 'root' on Fri Mar 25 20:07:24 EDT 2011 ************************************************************/ Re-format filesystem in /var/lib/hadoop-0.20/cache/hadoop/dfs/name ? (Y or N) Y 11/05/30 03:01:14 INFO util.GSet: VM type = 64-bit 11/05/30 03:01:14 INFO util.GSet: 2% max memory = 19.33375 MB 11/05/30 03:01:14 INFO util.GSet: capacity = 2^21 = 2097152 entries 11/05/30 03:01:14 INFO util.GSet: recommended=2097152, actual=2097152 11/05/30 03:01:14 INFO namenode.FSNamesystem: fsOwner=hdfs 11/05/30 03:01:14 INFO namenode.FSNamesystem: supergroup=supergroup 11/05/30 03:01:14 INFO namenode.FSNamesystem: isPermissionEnabled=false 11/05/30 03:01:14 INFO namenode.FSNamesystem: dfs.block.invalidate.limit=1000 11/05/30 03:01:14 INFO namenode.FSNamesystem: isAccessTokenEnabled=false accessKeyUpdateInterval=0 min(s), accessTokenLifetime=0 min(s) 11/05/30 03:01:16 INFO common.Storage: Image file of size 110 saved in 0 seconds. 11/05/30 03:01:16 INFO common.Storage: Storage directory /var/lib/hadoop-0.20/cache/hadoop/dfs/name has been successfully formatted. 11/05/30 03:01:16 INFO namenode.NameNode: SHUTDOWN_MSG: /************************************************************ SHUTDOWN_MSG: Shutting down NameNode at vCentOS/127.0.0.1 ************************************************************/
フォーマットできたらhdfsを起動してみます。
$ sudo /etc/init.d/hadoop-0.20-namenode start Starting Hadoop namenode daemon (hadoop-namenode): starting namenode, logging to /usr/lib/hadoop-0.20/logs/hadoop-hadoop-namenode-vCentOS.out $ sudo /etc/init.d/hadoop-0.20-datanode start Starting Hadoop datanode daemon (hadoop-datanode): starting datanode, logging to /usr/lib/hadoop-0.20/logs/hadoop-hadoop-datanode-vCentOS.out
ちなみに、logは /usr/lib/(略)-
.out を .log にしたファイルにログが入ってますので、何かおかしいかも、と思ったら .log を読みましょう。
んで、ちゃんと起動できたか確認。
/etc/init.d/ 以下のスクリプトに status で問い合わせればいいのだけど、個人的にinit.dスクリプトは信頼できない感じ。
さすがにもう直ったみたいだけど、インターンに行っていた時にはなぜかzookeeperのinit.dスクリプトが盛大にバグっていて、pidファイルの名前が違ってたり未定義の関数呼んでたりと……。何かと思ったよ。
で、まぁ、init.dスクリプトよりも(個人的に)おすすめなのがWebインターフェース。
namenodeならそのマシンの50070番ポートにHTTPでアクセスするとDFSの統計情報が見られます。
Cluster Summary 1 files and directories, 0 blocks = 1 total. Heap Size is 15.69 MB / 966.69 MB (1%) Configured Capacity : 29.91 GB DFS Used : 60 KB Non DFS Used : 4.25 GB DFS Remaining : 25.66 GB DFS Used% : 0 % DFS Remaining% : 85.78 % Live Nodes : 1 Dead Nodes : 0 Decommissioning Nodes : 0 Number of Under-Replicated Blocks : 0
見られない場合にはnamenodeの起動に失敗している(か、firewallとかネットワークの設定がおかしい)ので前述の .log ファイルで原因を探りましょう。
で、datanodeは、というと、そのWebインターフェースのCluster SummaryのLive Nodesで見られます。
Dead Nodesに数えられてないか、datanodeを起動したマシンが見えているか、などチェックしましょう。
で、ついでにHDFSのテスト。
この時点でHDFSはもう動いているので適当にlsしてみましょう。
$ sudo -u hdfs hadoop fs -ls / $
あ、ファイルがないや。
適当にディレクトリを作って確かめてみる。
$ sudo -u hdfs hadoop fs -mkdir /test $ sudo -u hdfs hadoop fs -lsr / drwxr-xr-x - hdfs supergroup 0 2011-05-30 03:12 /test
うん。ok。
MapRedの起動
HDFSは動いたのでお次はMapRed。
基本的にはHDFSと同じ。
$ sudo /etc/init.d/hadoop-0.20-jobtracker start Starting Hadoop jobtracker daemon (hadoop-jobtracker): starting jobtracker, logging to /usr/lib/hadoop-0.20/logs/hadoop-hadoop-jobtracker-vCentOS.out $ sudo /etc/init.d/hadoop-0.20-tasktracker start Starting Hadoop tasktracker daemon (hadoop-tasktracker): starting tasktracker, logging to /usr/lib/hadoop-0.20/logs/hadoop-hadoop-tasktracker-vCentOS.out
Webインターフェースのポート番号は50030。
Cluster SummaryのNodeの項がtasktrackerの一覧。
おっきいMapReduceを走らせるとWebインターフェー眺めているだけで幸せになれますw
で、MapRedを起動すると必要なディレクトリやらなんやらがHDFSに作られます。
$ sudo -u hdfs hadoop fs -lsr / drwxr-xr-x - hdfs supergroup 0 2011-05-30 03:12 /test drwxr-xr-x - mapred supergroup 0 2011-05-30 03:16 /var drwxr-xr-x - mapred supergroup 0 2011-05-30 03:16 /var/lib drwxr-xr-x - mapred supergroup 0 2011-05-30 03:16 /var/lib/hadoop-0.20 drwxr-xr-x - mapred supergroup 0 2011-05-30 03:16 /var/lib/hadoop-0.20/cache drwxr-xr-x - mapred supergroup 0 2011-05-30 03:16 /var/lib/hadoop-0.20/cache/mapred drwxr-xr-x - mapred supergroup 0 2011-05-30 03:16 /var/lib/hadoop-0.20/cache/mapred/mapred drwx------ - mapred supergroup 0 2011-05-30 03:16 /var/lib/hadoop-0.20/cache/mapred/mapred/system -rw------- 1 mapred supergroup 4 2011-05-30 03:16 /var/lib/hadoop-0.20/cache/mapred/mapred/system/jobtracker.info
そんなわけで、さっきも書きましたが所有者やらパーミッションやらはこういうのに任せるのが吉。
ただ、どのディレクトリがどいつの管轄なのか、とかは覚えておいたほうがいいと思います。
ちなみに、上のはHDFS上のデータなのですが、ローカルのファイルシステムにもsystemをlocalに変えたディレクトリが作られています。
別にHDFSとローカルのディレクトリでおなじ構成にいないといけないというルールはないので、わかりやすい名前に変えた方がいいとは思います。
今回はめんどく(ry、説明の簡便化を図るためにデフォルトのままでやってます。
デモを走らせる。
ちゃんと動いているようなので、デモを走らせてみます。
「Hadoop徹底入門」でも使われているpiをやってみます。
$ cd /usr/lib/hadoop-0.20/ $ sudo -u mapred hadoop jar hadoop-examples-0.20.2-cdh3u0.jar pi 1 10 Number of Maps = 1 Samples per Map = 10 Wrote input for Map #0 Starting Job 11/05/30 03:26:55 INFO mapred.FileInputFormat: Total input paths to process : 1 11/05/30 03:26:56 INFO mapred.JobClient: Running job: job_201105300316_0002 11/05/30 03:26:57 INFO mapred.JobClient: map 0% reduce 0% 11/05/30 03:27:09 INFO mapred.JobClient: map 100% reduce 0% 11/05/30 03:29:05 INFO mapred.JobClient: map 100% reduce 100% 11/05/30 03:29:08 INFO mapred.JobClient: Job complete: job_201105300316_0002 11/05/30 03:29:08 INFO mapred.JobClient: Counters: 23 11/05/30 03:29:08 INFO mapred.JobClient: Job Counters (略) 11/05/30 03:29:08 INFO mapred.JobClient: SPLIT_RAW_BYTES=118 11/05/30 03:29:08 INFO mapred.JobClient: Reduce input records=2 Job Finished in 133.411 seconds Estimated value of Pi is 3.60000000000000000000
Webインターフェースもいい感じ♪
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Running Jobs Jobid Priority User Name Map % Complete Map Total Maps Completed Reduce % Complete Reduce Total Reduces Completed Job Scheduling Information Diagnostic Info 100.00% 0.00% job_201105300316_0002 NORMAL mapred PiEstimator ┌─────────┐ 1 1 ┌─────────┐ 1 0 NA NA └─────────┘ └─────────┘ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
End-Of-Entry
そんなわけで円周率がおおよそ3.6ということが分かったところで、今回はこれまで。
次回はHBaseの導入とhbase shellと、あと余裕があればtwitterからデータを読み込んでみたりも。
そんなわけでまた次回。