絕大部分任務都很快完成,只有一個或者少數幾個任務執行的很慢甚至最終執行失敗, 這樣的現象為數據傾斜現象。
一定要和數據過量導致的現象區分開,數據過量的表現為所有任務都執行的很慢,這個 時候只有提高執行資源才可以優化 HQL 的執行效率。
綜合來看,導致數據傾斜的原因在于按照 Key 分組以后,少量的任務負責絕大部分數據 的計算,也就是說產生數據傾斜的 HQL 中一定存在分組操作,那么從 HQL 的角度,我們可 以將數據傾斜分為單表攜帶了 GroupBy 字段的查詢和兩表(或者多表)Join 的查詢。
1. 單表數據傾斜優化
1.1.?使用參數
當任務中存在 GroupBy 操作同時聚合函數為 count 或者 sum 可以設置參數來處理數據 傾斜問題。
是否在 Map 端進行聚合,默認為 True
set hive.map.aggr = true;
在 Map 端進行聚合操作的條目數目
set hive.groupby.mapaggr.checkinterval = 100000;
有數據傾斜的時候進行負載均衡(默認是 false)
set hive.groupby.skewindata = true;
當選項設定為 true,生成的查詢計劃會有兩個 MR Job。
1.2. 增加 Reduce 數量(多個 Key 同時導致數據傾斜)
1)調整 reduce 個數方法一
(1)每個 Reduce 處理的數據量默認是 256MB
set hive.exec.reducers.bytes.per.reducer = 256000000
(2)每個任務最大的 reduce 數,默認為 1009
set hive.exec.reducers.max = 1009
(3)計算 reducer 數的公式
N=min(參數 2,總輸入數據量/參數 1)(參數 2 指的是上面的 1009,參數 1 值得是 256M)
2)調整 reduce 個數方法二
在 hadoop 的 mapred-default.xml 文件中修改
設置每個 job 的 Reduce 個數
set mapreduce.job.reduces = 15;
2. Join 數據傾斜優化
2.1. 使用參數
在編寫 Join 查詢語句時,如果確定是由于 join 出現的數據傾斜,那么請做如下設置:
# join 的鍵對應的記錄條數超過這個值則會進行分拆,值根據具體數據量設置
set hive.skewjoin.key=100000;
# 如果是 join 過程出現傾斜應該設置為 true
set hive.optimize.skewjoin=false;
如果開啟了,在 Join 過程中 Hive 會將計數超過閾值 hive.skewjoin.key(默認 100000)的 傾斜 key 對應的行臨時寫進文件中,然后再啟動另一個 job 做 map join 生成結果。通過 hive.skewjoin.mapjoin.map.tasks 參數還可以控制第二個 job 的 mapper 數量,默認 10000。
set hive.skewjoin.mapjoin.map.tasks=10000;