Hadoop運用あれこれ

今回はHadoopを運用してみてのメモです。

エラー系

■The reduce copier failed

ログ

java.io.IOException: Task: attempt_xxxxxx - The reduce copier failed
    at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:380)
    at org.apache.hadoop.mapred.Child.main(Child.java:170)
Caused by: java.io.IOException: Intermediate merge failed
    at org.apache.hadoop.mapred.ReduceTask$ReduceCopier$InMemFSMergeThread.doInMemMerge(ReduceTask.java:2651)
    at org.apache.hadoop.mapred.ReduceTask$ReduceCopier$InMemFSMergeThread.run(ReduceTask.java:2576)
Caused by: java.lang.RuntimeException: java.io.EOFException
    at org.apache.hadoop.io.WritableComparator.compare(WritableComparator.java:128)
    at org.apache.hadoop.mapred.Merger$MergeQueue.lessThan(Merger.java:373)
    at org.apache.hadoop.util.PriorityQueue.downHeap(PriorityQueue.java:139)
    at org.apache.hadoop.util.PriorityQueue.adjustTop(PriorityQueue.java:103)
    at org.apache.hadoop.mapred.Merger$MergeQueue.adjustPriorityQueue(Merger.java:335)
    at org.apache.hadoop.mapred.Merger$MergeQueue.next(Merger.java:350)
    at org.apache.hadoop.mapred.Merger.writeFile(Merger.java:156)
    at org.apache.hadoop.mapred.ReduceTask$ReduceCopier$InMemFSMergeThread.doInMemMerge(ReduceTask.java:2635)

解決策
ヒープメモリのサイズを増やす。一応最小値も設定してみました。
mapred-site.xml

  <property>
    <name>mapred.child.java.opts</name>
    <value>-Xmx2048m -Xms1024m</value>
  </property>

参考
Hadoop クラスタ構成時のハードウェア選定の目安
メモリ大事です。

■No space left on device

ログ

FSError: java.io.IOException: No space left on device

解決策
処理結果を出力するための容量がないのでHDFS上から不要なデータを消去

先ほどのHadoop クラスタ構成時のハードウェア選定の目安を参考に見積りを誤らなければ出ないログですね。

チューニング系

■map処理が遅い

ログ

INFO org.apache.hadoop.mapred.MapTask: Spilling map output: record full = true

Spillのログが大量に出てました。
さらにmap処理の最後で

INFO org.apache.hadoop.mapred.Merger: Merging 40 intermediate segments out of a total of 157

Mergeのログが出てます。

このSpillとMergeについてざっと調べてみたのでまとめ

・Spill
まずmapタスクは処理した結果をメモリ上に保持します。
 →メモリ(バッファ領域)が足りなくなるとディスクへの書き込みが発生=これがSpill
   →ディスクに書き込む為に時間がかかる(書き込まれたデータをセグメントという)

・Merge
mapタスクの最後でディスクに書き込まれたセグメントをMergeする
 →セグメント数が多いとMerge時間がかかる

ではチューニング
map処理の結果を格納するメモリのバッファ領域には下記の2つを格納します。
 ①データ領域
 ②レコード領域

バッファ領域の設定(例.250MBに設定)
mapred-site.xml

  <property>
    <name>io.sort.mb</name>
    <value>250</value>
  </property>

バッファ領域の内、②レコード領域を格納するためのサイズを指定
このPropertyは最近のバージョンでは無くなっているようです。

  <property>
    <name>io.sort.record.percent</name>
    <value>0.05</value>
  </property>

デフォルトではio.sort.mbで指定したサイズの5%が②レコード領域になります。
そして残りが①データ領域になります。

ディスクに書き込む=spillする閾値の設定
デフォルトでは領域の80%になるとspillされます。

  <property>
    <name>io.sort.spill.percent</name>
    <value>0.80</value>
  </property>

先ほどのログを見ると”record full”となっているのでレコード領域が
設定したバッファの80%以上になったのでspillされているようです。
なのでレコード領域のサイズを変更してやればspillされる頻度が減ることがわかります。

今日はここまで。またノウハウが溜まってくれば書こうと思います。
日々勉強なり。(ノ´▽`)ノ{+++THANK YOU+++}ヽ(´▽`ヽ)

Hadoop徹底入門 第2版 オープンソース分散処理環境の構築

Hadoop徹底入門 第2版 オープンソース分散処理環境の構築

広告を非表示にする