1. 程式人生 > 實用技巧 >hive.groupby.skewindata及資料傾斜優化

hive.groupby.skewindata及資料傾斜優化

一、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 組合的坑

參考:

hive資料傾斜原理與解決方案

hive原理與原始碼分析


學習交流,有任何問題還請隨時評論指出交流。