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