天天看點

MaxCompute參數調優

1 背景及目的

對于ODPS上的運作時間長的任務來說,針對不同的問題有不同的優化方法(詳見其他章節)。但是對于一些特殊場景的任務來說,除了從業務上可以進行優化之外,還需要通過一些輔助的參數設定才能達到比較好的優化效果。是以,ODPS提供了很多性能參數供開發人員使用。

2 參數介紹

2.1 資源參數

ODPS處理一個任務主要分為三個階段:Map、Reduce、Join。如果處理的資料量比較大,導緻各個階段的每個Instance處理的的時間比較長,在沒有發生傾斜的情況下,可以通過設定下面的資源參數增加資源來加快處理速度。

2.1.1 Map設定

set odps.sql.mapper.cpu=100

作用:設定處理Map Task每個Instance的CPU數目,預設為100,在[50,800]之間調整。

場景:某些任務如果特别耗計算資源的話,可以适當調整Cpu數目。對于大多數Sql任務來說,一般不需要調整Cpu個數的。

set odps.sql.mapper.memory=1024

作用:設定Map Task每個Instance的Memory大小,機關M,預設1024M,在[256,12288]之間調整。

場景:當Map階段的Instance有Writer Dumps時,可以适當的增加記憶體大小,減少Dumps所花的時間。

set odps.sql.mapper.merge.limit.size=64

作用:設定控制檔案被合并的最大門檻值,機關M,預設64M,在[0,Integer.MAX_VALUE]之間調整。

場景:當Map端每個Instance讀入的資料量不均勻時,可以通過設定這個變量值進行小檔案的合并,使得每個Instance的讀入檔案均勻。一般會和odps.sql.mapper.split.size這個參數結合使用。

set odps.sql.mapper.split.size=256

作用:設定一個Map的最大資料輸入量,可以通過設定這個變量達到對Map端輸入的控制,機關M,預設256M,在[1,Integer.MAX_VALUE]之間調整。

場景:當每個Map Instance處理的資料量比較大,時間比較長,并且沒有發生長尾時,可以适當調小這個參數。如果有發生長尾,則結合odps.sql.mapper.merge.limit.size這個參數設定每個Map的輸入數量。

2.1.2 Join設定

set odps.sql.joiner.instances=-1

作用: 設定Join Task的Instance數量,預設為-1,在[0,2000]之間調整。不走HBO優化時,ODPS能夠自動設定的最大值為1111,手動設定的最大值為2000,走HBO時可以超過2000。

場景:每個Join Instance處理的資料量比較大,耗時較長,沒有發生長尾,可以考慮增大使用這個參數。

set odps.sql.joiner.cpu=100

作用: 設定Join Task每個Instance的CPU數目,預設為100,在[50,800]之間調整。

場景:某些任務如果特别耗計算資源的話,可以适當調整CPU數目。對于大多數SQL任務來說,一般不需要調整CPU。

set odps.sql.joiner.memory=1024

作用:設定Join Task每個Instance的Memory大小,機關為M,預設為1024M,在[256,12288]之間調整。

場景:當Join階段的Instance有Writer Dumps時,可以适當的增加記憶體大小,減少Dumps所花的時間。

2.1.3 Reduce設定

set odps.sql.reducer.instances=-1

作用: 設定Reduce Task的Instance數量,預設為-1,在[0,2000]之間調整。不走HBO優化時,ODPS能夠自動設定的最大值為1111,手動設定的最大值為2000,走HBO優化時可以超過2000。

set odps.sql.reducer.cpu=100

作用:設定處理Reduce Task每個Instance的Cpu數目,預設為100,在[50,800]之間調整。

場景:某些任務如果特别耗計算資源的話,可以适當調整Cpu數目。對于大多數Sql任務來說,一般不需要調整Cpu。

set odps.sql.reducer.memory=1024

作用:設定Reduce Task每個Instance的Memory大小,機關M,預設1024M,在[256,12288]之間調整。

場景:當Reduce階段的Instance有Writer Dumps時,可以适當的增加記憶體的大小,減少Dumps所花的時間。

上面這些參數雖然好用,但是也過于簡單暴力,可能會對叢集産生一定的壓力。特别是在叢集整體資源緊張的情況下,增加資源的方法可能得不到應有的效果,随着資源的增大,等待資源的時間變長的風險也随之增加,導緻效果不好!是以請合理的使用資源參數!

2.2 小檔案合并參數

set odps.merge.cross.paths=true|false

作用:設定是否跨路徑合并,對于表下面有多個分區的情況,合并過程會将多個分區生成獨立的Merge Action進行合并,是以對于odps.merge.cross.paths設定為true,并不會改變路徑個數,隻是分别去合并每個路徑下的小檔案。

set odps.merge.smallfile.filesize.threshold = 64

作用:設定合并檔案的小檔案大小閥值,檔案大小超過該閥值,則不進行合并,機關為M,可以不設,不設時,則使用全局變量odps_g_merge_filesize_threshold,該值預設為32M,設定時必須大于32M。

set odps.merge.maxmerged.filesize.threshold = 256

作用:設定合并輸出檔案量的大小,輸出檔案大于該閥值,則建立新的輸出檔案,機關為M,可以不設,不設時,則使用全局變odps_g_max_merged_filesize_threshold,該值預設為256M,設定時必須大于256M。

set odps.merge.max.filenumber.per.instance = 10000

作用:設定合并Fuxi Job的單個Instance允許合并的小檔案個數,控制合并并行的Fuxi Instance數,可以不設,不設時,則使用全局變量odps_g_merge_files_per_instance,該值預設為100,在一個Merge任務中,需要的Fuxi Instance個數至少為該目錄下面的總檔案個數除以該限制。

set odps.merge.max.filenumber.per.job = 10000

作用:設定合并最大的小檔案個數,小檔案數量超過該限制,則超過限制部分的檔案忽略,不進行合并,可以不設,不設時,則使用全局變量odps_g_max_merge_files,該值預設為10000。

2.3 UDF相關參數

set odps.sql.udf.jvm.memory=1024

作用: 設定UDF JVM Heap使用的最大記憶體,機關M,預設1024M,在[256,12288]之間調整。

場景:某些UDF在記憶體計算、排序的資料量比較大時,會報記憶體溢出錯誤,這時候可以調大該參數,不過這個方法隻能暫時緩解,還是需要從業務上去優化。

set odps.sql.udf.timeout=600

作用:設定UDF逾時時間,預設為600秒,機關秒。[0,3600]之間調整。

set odps.sql.udf.python.memory=256

作用:設定UDF python 使用的最大記憶體,機關M,預設256M。[64,3072]之間調整。

set odps.sql.udf.optimize.reuse=true/false

作用:開啟後,相同的UDF函數表達式,隻計算一次,可以提高性能,預設為True。

set odps.sql.udf.strict.mode=false/true

作用:True為金融模式,False為淘寶模式,控制有些函數在遇到髒資料時是傳回NULL還是抛異常,True是抛出異常,False是傳回null。

2.4 Mapjoin設定

set odps.sql.mapjoin.memory.max=512

作用:設定Mapjoin時小表的最大記憶體,預設512,機關M,[128,2048]之間調整。

2.5 動态分區設定

set odps.sql.reshuffle.dynamicpt=true/false

作用:False:會減少小檔案的産生,如果動态分區值很少,關閉資料就不會傾斜了。True:不會資料傾斜。

2.6 資料傾斜設定

set odps.sql.groupby.skewindata=true/false

作用:開啟Group By優化。

set odps.sql.skewjoin=true/false

作用:開啟Join優化,必須設定odps.sql.skewinfo 才有效。

set odps.sql.skewinfo

作用:設定join優化具體資訊,格式:set odps.sql.skewinfo=skewed_src:(skewed_key)[("skewed_value")]例子:針對單個字段單個傾斜數值

set odps.sql.skewinfo=src_skewjoin1:(key)[("0")]

explain select a.key c1, a.value c2, b.key c3, b.value c4 from src a join src_skewjoin1 b on a.key = b.key;

針對單個字段多個傾斜數值

set odps.sql.skewinfo=src_skewjoin1:(key)[("0")("1")]

2.7 Sevice Mode

odps.service.mode=limited/all/off

作用:開啟/關閉準實時模式,限制腳本運作時間,預設為Off。

例子:set odps.service.mode=all開啟後任務逾時會出現:

failed:instance running interval is over live time(600)

注:Limited表示盡量使用Service Mode,All表示強制使用。

3 案例介紹

Map Split塊大小設定,即調整Map Instance的個數,預設為:

set odps.sql.mapper.split.size=256p_w_picpath

調整Split Size後:

set odps.sql.mapper.split.size=128

計算時間減少1倍,因為檔案塊小了,那麼導緻輸出的時候就有大量的小檔案需要合并,合并時間增大4倍,得不償失。p_w_picpath

繼續設定:

set odps.sql.mapper.split.size=192

可以看到在計算時間和合并檔案的時間都達到一個平衡點:p_w_picpath

總結:mapper.split.size的大小要慎重設定,否則會出現這個任務快了,其它的任務慢了,這是一個互相平衡的過程。

4 總結

盡量不要通過設定參數的方式進行優化,首先要看能否從業務上或者算法上減少資料和其他方式進行優化。

設定參數的話,要首先确定是Map、Reduce、Join哪個階段的任務時間長,進而設定對應的參數。

在沒有出現資料傾斜的情況下,如果通過設定Cpu參數(含Memory參數)和設定Instance個數兩種方式都能調優的話,最好是先設定Instance個數。因為如果Cpu/Memory參數設定不合理,執行任務的機器滿足不了參數的要求,要重新找機器的,這樣反而會影響效率。如果執行日志中出現Dump,最好是Instance個數和Memory都增大一下。

Instance的個數設定,有個簡單的方法是二分法。先設定個很大的,如果不能滿足要求,那麼就繼續增大,如果滿足了要求,就折半降低參數大小,最終找到一個合适的值。

繼續閱讀