生物物理計算化学者の雛

主に科学に関する諸々を書き留めています。

MapReduceジョブのOutOfMemoryErrorに対処する

Hadoopジョブを実行しているとよく map や reduce 処理でヒープ領域が足りないというエラーに遭遇します。

例えばこれは reduce 実行時にヒープ領域が足りないというエラーメッセージの一部です。(Hadoop 0.21.0 の場合)

org.apache.hadoop.mapreduce.task.reduce.Shuffle$ShuffleError: error in shuffle in fetcher#4 at 
org.apache.hadoop.mapreduce.task.reduce.Shuffle.run(Shuffle.java:124) at 
org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:362) at 
org.apache.hadoop.mapred.Child$4.run(Child.java:217) at 
java.security.AccessController.doPrivileged(Native Method) at 
javax.security.auth.Subject.doAs(Subject.java:396) at 
org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:742) at 
org.apache.hadoop.mapred.Child.main(Child.java:211) 
Caused by: java.lang.OutOfMemoryError: Java heap space 
at org.apache.hadoop.io.BoundedByteArrayOutputStream.(BoundedByteArrayOutputStream.java:58) at 
org.apache.hadoop.io.BoundedByteArrayOutputStream.(BoundedByteArrayOutputStream.java:45) at 
org.apache.hadoop.mapreduce.task.reduce.MapOutput.(MapOutput.java:104) at 
org.apache.hadoop.mapreduce.task.reduce.MergeManager.unconditionalReserve(MergeManager.java:267) at 
org.apache.hadoop.mapreduce.task.re ...

reduce関数でのメモリ不足であれば mapreduce.reduce.java.opts オプションでより多くのヒープ領域を指定することで回避できます。
(map関数であれば mapreduce.map.java.opts を変更します。)
 

設定ファイルを書きかえる

恒常的にメモリ確保量を大きくしたいのであれば、$HADOOP_HOME/conf/mapred-site.xml

 
  mapreduce.reduce.java.opts
  -Xmx1000m
 

のように大きなメモリサイズ(この場合 1000MB = 1GB) を指定します。
なお hadoop ジョブを起動するマシンの mapred-site.xml の内容が読み込まれてジョブに反映されます。

ジョブ実行時にオプション指定する

ある実行ジョブだけ大きくしたいなら

hadoop jar myHadoopProgram.jar \
   myHadoopProgram.MapReduceJob \
   -Dmapreduce.reduce.java.opts=-Xmx1000m  \
   parm1 parm2
(-D はクラス名の次に書かないとダメ)

のようにオプションを指定できます。
オプション指定 -D はクラス名(この例なら myHadoopProgram.MapReduceJob)の直後に書かないと認識されませんので注意してください。