hive.groupby.skewindata及資料傾斜優化
阿新 • • 發佈:2021-01-21
一、hive.groupby.skewindata
set hive.groupby.skewindata=true;
資料傾斜時負載均衡,當選項設定為true,生成的查詢計劃會有兩個MRJob。第一個MRJob 中,Map的輸出結果集合會隨機分佈到Reduce中,每個Reduce做部分聚合操作,並輸出結果,這樣處理的結果是相同的GroupBy Key有可能被分發到不同的Reduce中,從而達到負載均衡的目的;第二個MRJob再根據預處理的資料結果按照GroupBy Key分佈到Reduce中(這個過程可以保證相同的GroupBy Key被分佈到同一個Reduce中),最後完成最終的聚合操作。
由上圖下部分過程可看到過程,由此帶出解決資料傾斜的方式。
二、關於資料傾斜出現原因:
- 對於join過程來說,如果出項較多的key值為空或異常的記錄,或key值分佈不均勻,就容易出現數據傾斜。
- 對於group by 過程來說,如果某一個key值有特別的多的記錄,其它key值的記錄比較少,也容易出項資料傾斜。
Join實現原理舉例:
select name, orderidf
from user t1
join order t2 on t1.uid=t2.uid
Group by實現原理舉例
sql = select rank, isonline, count(1) from city group by 1, 2
三、資料傾斜的解決方案
①、join引起資料傾斜的解決方法
- 如果是由於key值為空或為異常記錄,且這些記錄不能被過濾掉的情況下,可以考慮給key賦一個隨機值,將這些值分散到不同的reduce進行處理。
- 如果是一個大表和一個小表join的話,可以考慮使用mapjoin來避免資料傾斜。
mapjoin原理可參考前一篇文章:淺談Hive中Map Join原理及場景
②、group by 引起資料傾斜的解決方法
set hive.map.aggr=true;
在map中會做部分聚集操作,效率更高但需要更多的記憶體。開啟map之後使用combiner,這樣基本上是對各記錄比較同質的資料效果比較好,相反,則沒有什麼意義。通用的做法是設定下面兩個引數:
set hive.groupby.mapaggr.checkinterval = 100000 (預設)執行聚合的條數
set hive.map.aggr.hash.min.reduction=0.5(預設)
#如果hash表的容量與輸入行數之比超過這個數,那麼map端的hash聚合將被關閉,預設是0.5,
#設定為1可以保證hash聚合永不被關閉;
還有一個方式是本文提及的set hive.groupby.skewindata=true
ps: 有博文反應該引數與set hive.map.aggr=true同時使用時候對distinct結果會有影響,但我實測並沒有,可能是特定情況才會出現?如若碰到還請隨時交流。hive.groupby.skewindata 和 hive.map.aggr 組合的坑
參考:
學習交流,有任何問題還請隨時評論指出交流。