No Such Blog or Diary
Hadoop で忘れがちな点
ひとつのファイルは HDFS 上に物理的にチャンクに区切られて置かれる.FileSplit はひとつのファイルを論理的に区切ったもの.ひとつの FileSplit に対して Map のジョブひとつが対応して実行される.細かくは,ひとつの FileSplit がひとつの RecordReader を生成し,その RecordReader がその Map ジョブへと Key/Valueペアのリストを提供する.このとき,その RecordReader はその FileSplit で指定された論理的な領域を越えて(HDFS上にあるだろう)元のファイルを読み込むことが出来る.
一般に,HDFSのチャンクはFileSplitではないし,FileSplitとMapジョブに提供される仕事とは完全に一致はしない.
実際,デフォルトのTextInputFormatが作るRecordReaderは,与えられたFileSplitの最終行を完成させるため,次のFileSplitの境域へと境界を越えて最後の行を読みに行く.例えば,改行なしの大きなファイルを入力とすれば,最初のFileSplitから作られたRecoardReaderは改行を求めてファイル全部を読んでしまう.結果として,先頭のMapジョブはファイル全体を入力として受け取る.
- Comments: 0
- TrackBack (Close): -
Hadoop に言うことを聞かせるまでのメモ
大体にしてインストールというかセッティングが面倒なので手順のメモ.
- ダウンロードして展開.クラスタの場合,本体の置き場所は NFS 上にしとくとインストールが楽(ログのディレクトリに注意).さもなければ全マシンの同じパスに置いておくべし(パスをマシンごとに変えていいのかどうか分からん).
wget http://ftp.kddilabs.jp/infosystems/apache//hadoop/core/hadoop-0.21.0/hadoop-0.21.0.tar.gz tar xfvz hadoop-0.21.0.tar.gz cd hadoop-0.21.0
- 環境ファイル conf/hadoop-env.sh の編集:JAVA_HOME と HADOOP_HEAPSIZE と HADOOP_LOG_DIR.
ログの出力先はデフォルトで hadoop の置いてあるディレクトリ(HADOOP_HOME)の下の logs ディレクトリなので,これが NFS 上だったりすると酷いことになる.なので,ローカル上に取るように指定を入れておく.
export JAVA_HOME=/usr/lib/jvm/java-6-sun/ export HADOOP_HEAPSIZE=2048 export HADOOP_LOG_DIR=/tmp/user/node000/logs
- 設定ファイル conf/slaves:計算に使うノード名を列挙.
node000 node001 node002 node003 ...
- 設定ファイル conf/core-site.xml の編集.
namenode として使う計算機の名前(URI)を書いておく.マルチコア計算機1台なら localhost で十分.クラスタの場合には localhost ではまずいので,ちゃんとした計算機名前を書いておく.
<configuration> <property> <name>fs.default.name</name> <value>hdfs://node000:9000/</value> </property> </configuration>
- 設定ファイル conf/hdfs-site.xml の編集.
dfs.name.dir と dfs.data.dir に /tmp とかローカルなディスクのパスを書いておく(設定書かなくてもデフォルトで /tmp に適当なディレクトリを作って使ってくれるけど).NFS上のパスを指定するのは何考えているか分からない.あとは dfs.blocksize (HDFS上のチャンクのサイズ)を適当に変えてもいいかも知れない.Mapper への一仕事の最大値はこのサイズ.
<configuration> <property> <name>dfs.name.dir</name> <value>/tmp/user/node000/name-dir/</value> </property> <property> <name>dfs.data.dir</name> <value>/tmp/user/node000/data-dir/</value> </property> <property> <name>dfs.blocksize</name> <value>4194304</value> </property> </configuration>
- 設定ファイル conf/mapred-site.xml の編集.
とりあえず,mapred.job.tracker に JobTracker のいる計算機の名前を書いておく.マルチコア1台なら localhost で十分.クラスタなら計算機名をちゃんとかく.あと,計算が軽い時には JVM を使い回さないと遅くて困るので mapred.job.reuse.jvm.num.tasks に無限回の使い回しを意味する -1 を入れておく.ノード一つ当たりのジョブの数は mapred.tasktracker.map.tasks.maximum と mapred.tasktracker.reduce.tasks.maximum で指定しておく.マルチコアならコア数以上のジョブが同時にあって構わないので,コア数以上の数字を書いておく(2コアマシンしか無いのに200とか書くとプロセスが多すぎて死ぬ).また,Hadoop ではひとつのファイルを複数の FileSplit に分割し,その FileSplit 1つに対して Mapper が1つ呼ばれて動く(間に RecordReader が挟まって「FileSplit→KVペアの集合」という変換が入るけど).その FileSplit のサイズ指定が mpreduce.input.fileinputformat.split.maxsize でできる.実際には,これで指定したサイズと HDFS のチャンクサイズとの小さいほうが実際の FileSplit のサイズになる(全タスク数の指定を入れたときには,さらにそこから導かれるサイズとの小さいほうかね).
<configuration> <property> <name>mapred.job.reuse.jvm.num.tasks</name> <value>-1</value> </property> <property> <name>mapred.job.tracker</name> <value>node000:9001</value> </property> <property> <name>mapred.tasktracker.map.tasks.maximum</name> <value>2</value> </property> <property> <name>mapred.tasktracker.reduce.tasks.maximum</name> <value>2</value> </property> <property> <name>mapreduce.input.fileinputformat.split.maxsize</name> <value>4194304</value> </property> </configuration>
- テスト.
namenode を初期化して,他のノードを起動して,最初にディレクトリ作って,そこにファイルを転送して,サンプル動かして,出力確認して,邪魔な出力消して,そしてノード停止.
bin/hadoop namenode -format bin/start-all.sh bin/hadoop fs -mkdir input bin/hadoop fs -put conf/* input bin/hadoop jar hadoop-mapred-examples-0.21.0.jar grep input output 'dfs[a-z.]+' bin/hadoop fs -cat output/* bin/hadoop fs -rmr output bin/stop-all.sh
これで言う事聞くようになった.
その他無茶な設定 in conf/mapred-site.xml:なるべくディスクつかなわいように無理をする.
<property> <name>io.sort.record.percent</name> <value>1.0</value> </property> <property> <name>io.sort.spill.percent</name> <value>1.0</value> </property> <property> <name>io.sort.mb</name> <value>4</value> </property> <property> <name>mapred.inmem.merge.threshold</name> <value>2048</value> </property> <property> <name>mapred.job.reduce.input.buffer.percent</name> <value>1.0</value> </property> <property> <name>mapred.job.shuffle.input.buffer.percent</name> <value>1.0</value> </property> <property> <name>mapred.job.shuffle.merge.percent</name> <value>1.0</value> </property>
- Comments: 0
- TrackBack (Close): -
Hadoop に言う事を聞かせられるようになってきた
- 2011-02-14 (Mon)
- 一般
ラインごとに Mapper に渡さなくていい,まとめて寄越せ → 自前で FileSplit 全体を Mapper に与える RecordReader を実装.中身はすっからかんだけどね.
bin/hadoop namenode -format して bin/start-all.sh して bin/hadoop fs -put hoge.dat . とかすると文句を言われる → bin/hadoop fs -mkdir tmp してから bin/hadoop fs -put hoge.dat . すると文句を言われない.からの状態からディレクトリを何でもいいからひとつ作ってやると,ホームディレクトリ(.)にファイルを置ける.というか,mkdir でディレクトリ作ったときにホームディレクトリもついでに作られるからなのか? とにかくディレクトリを先に作っておかないとファイルを置けないのかね?
mapreduce の FileSplit のサイズは mapred-site.xml でmapreduce.input.fileinputformat.split.maxsize を指定.
bin/hadoop --config conf-hoge ... とかで設定ファイルを切り替えられる.start から stop まで一貫して同じ設定を使わないと色々とおかしくなってくれるけど.
- Comments: 0
- TrackBack (Close): -
曽我の梅林へ
曽我の梅林へ梅を見に行った.10時過ぎには大学にいく必要があったので,日の出前に梅林に到着.路面が凍結しているので危ない.特に止まった時が一番危ない.気を受けないと付いた足が滑って立ちゴケする.コケなかったけど.走行距離200キロ.
んで,別所梅林.ここらの梅林全体をまとめて曽我梅林と呼んで,別所梅林はその中のひとつってことでいいのかな.よく解らんけど蘇我の梅林に行こうと言っていつも来ていたのはここだったはず.
雪の降った翌日の早朝なので,寒いシリーズ:赤富士,雪をかぶった箱根の山,朝日.
蘇我の梅林は好き勝手に入り込める点が良い.好きなように梅が見られるし,地面の草も良い感じ…… 寒すぎて凍ってたれど.昼間ならきれいな緑の地面と青い空と白い梅とか撮れるはず.でも地面が凍っているので白い梅と早朝の青空.
そして帰りの東名高速で事故のために渋滞発生.おかげで大学に行くのが微妙に遅れてしまった.迷惑だから自爆でも事故るな.
- Comments: 0
- TrackBack (Close): -
Hadoop が言うこと聞かない
- 2011-02-12 (Sat)
- 一般
Hadoop のオンラインドキュメントが腐っていたというオチだったのだけど… HDFS へのディレクトリの転送がおかしい気がする.
さて,次はファイルからの読み込み部分をカスタマイズしにかかろう.FileSplit の境界を超えた部分の扱いが今ひとつ理解出来ていないのだけど… 自分で実装するときにはどうやって境界超えた端数を持ってくるんだ?
- Comments: 0
- TrackBack (Close): -