mapreduce作業調優tips

  這幾天一直在優化job,下面是我認爲有用的一些tips。

  1. 推測執行在整個集羣上關閉,特定需要的作業單獨開啓,一般可以省下約5%~10%的集羣資源。由mapred.map.task.speculative.execution[default true]和mapred.reduce.task.speculative.execution[default true]分別控制map和reduce的推測執行開關。
    mapred.map.task.speculative.execution=true;
    mapred.reduce.task.speculative.execution=false;
  2. task執行時間很短的時候,關閉推測執行(否則可能會有約5%的task被kill掉,而你會觀察到通常kill的是因推測執行而額外啓動的tasks)。
  3. 在map時間很長,而map的輸出數據並不大的時候,推遲reduce執行時間(否則在推測執行打開的時候會看到有大量的reduce task attempts因過早啓動而被kill掉,過早啓動會導致集羣資源被浪費),這個由mapred.reduce.slowstart.completed.maps[default 0.05,即5%]控制,我甚至看到有的job因爲這個kill掉了2*reduceNum以上的task attempts。集羣把這個參數設置爲0.75應該比較合適。
    mapred.reduce.slowstart.completed.maps=0.80
  4. 當task數量非常多而且通常很短[約1min]的時候,把JVM重用開啓,由mapred.job.reuse.jvm.num.tasks[default 1]控制,這通常能獲得10%以上的執行時間減少。當節點數量在100個以內,而task數量高達5000以上的時候,可以直接設置爲-1[意味着重用個數不限制]。
    mapred.job.reuse.jvm.num.tasks=-1
  5. io.sort.mb被用作map輸出的buffer,當buffer使用達到某個閾值的時候會進行sort然後spill到磁盤,默認地io.sort.mb[default 100,即100Mb]通常過小[過小會導致寫磁盤次數很多,spill文件也很多],在輸出數據量較大的時候建議調整到300左右,建議不要更大,否則sort會很很慢[快排nlogn,先快排後merge的分治手段在大數據情況下更好]。
    io.sort.mb=300
  6. mapred.reduce.parallel.copies控制着reduce從map拉取數據時開啓的線程數量[default 5],在輸出數據很多,特別是map數量也很多的時候,建議調到15或者更大,否則reduce的copy階段可能很慢[map已經完成,而reduce還處於遠沒到33%]。
    mapred.reduce.parallel.copies=15
  7. 對map輸出進行壓縮可以減少磁盤io和reduce的copy時間,設置爲:
      mapred.compress.map.output=true;
      mapred.map.output.compression.codec=com.hadoop.compression.lzo.LzoCodec;
  8. 當map輸入數據量很大,map個數特別多,但是map執行時間卻很短[約1min,通常是因爲計算只涉及部分輸入數據]的時候,把map的輸入分片調大到兩倍block大小[default block大小]可能獲得更好的執行效率。注意到這可能影響數據本地化的利用,不過我的經驗是在這種情況下調大會更好。
    mapred.min.split.size=268435456 
  9. io.sort.factor[default 10]控制着合併spill文件時同時打開的spill文件數量,當spill文件很多時,此值太小會導致需要合併的次數很多,當數據量大的時候應該調高一些。
    io.sort.factor=50
  10. 壓縮reduce輸出,常用LZO
  11. 下面的參數通常使用默認值,但也可以稍微調節
    mapred.job.shuffle.input.buffer.percent=0.8
    mapred.job.shuffle.merge.percent=0.8
    io.sort.spill.percent=0.9#輸入數據比較有序時,否則可能導致阻塞map任務輸出

通常調節執行參數是寫完code之後根據執行情況調節的,如果調節後執行情況還很差,就需要對代碼進行優化。

我們可以使用HPROF工具對代碼進行性能分析,以便觀察各個操作CPU使用情況和內存分配情況,從而針對性地優化,使用HPROF會導致被分析的task執行十分緩慢,因此千萬別對所有task都使用分析。

關於HPROF工具的使用,具體見,參看這裏。另外是oracle的官方文檔,這裏:HPROF: A Heap/CPU Profiling Tool 可以瞭解更多HPROF的內容。


某種程度上說,job的執行效率主要取決於使用的算法。但在實際環境中很多人在寫job的時候可能忽略參數調節和性能分析的過程,而導致job運行過慢。這需要一個比較完善的code review規範和監控系統。總的來說,建議對所有job都調節參數,對將長期執行的大型的job進行性能分析優化。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章