hive-資料傾斜解決詳解
hive在跑資料時經常會出現資料傾斜的情況,使的作業經常reduce完成在99%後一直卡住,最後的1%花了幾個小時都沒跑完,這種情況就很可能是資料傾斜的原因,解決方法要根據具體情況來選擇具體的方案
1、join的key值發生傾斜,key值包含很多空值或是異常值
這種情況可以對異常值賦一個隨機值來分散key
如:
selectuserid , name
fromuser_info a
join (
select case when userid is null then cast ( rand ( 47 )* 100000 as i nt )
elseuserid
fromuser_read_log
)b on a . userid = b . userid
通過rand函式將為null的值分散到不同的值上,在key值比較就能解決資料傾斜的問題
注:對於異常值如果不需要的話,最好是提前過濾掉,這樣計算量可以大大減少
2、當key值都是有效值時,解決辦法為設定以下幾個引數
set hive.exec.reducers.bytes.per.reducer = 1000000000
也就是每個節點的reduce 預設是處理1G大小的資料,如果你的join 操作也產生了資料傾斜,那麼你可以在hive 中設定
set hive.optimize.skewjoin = true;
set hive.skewjoin.key = skew_key_threshold (default = 100000)
hive 在執行的時候沒有辦法判斷哪個key 會產生多大的傾斜,所以使用這個引數控制傾斜的閾值,如果超過這個值,新的值會發送給那些還沒有達到的reduce, 一般可以設定成你
(處理的總記錄數/reduce個數)的2-4倍都可以接受.
傾斜是經常會存在的,一般select 的層數超過2層,翻譯成執行計劃多於3個以上的mapreduce job 都很容易產生傾斜,建議每次執行比較複雜的sql 之前都可以設一下這個引數. 如果你不知道設定多少,可以就按官方預設的1個reduce 只處理1G 的演算法,那麼 skew_key_threshold = 1G/平均行長. 或者預設直接設成250000000 (差不多算平均行長4個位元組)
3、reduce數太少
set mapred.reduce.tasks=800;
預設是先設定hive.exec.reducers.bytes.per.reducer這個引數,設定了後hive會自動計算reduce的個數,因此兩個引數一般不同時使用
4、對於group by 產生傾斜的問題
set hive.map.aggr=true (開啟map端combiner); //在Map端做combiner,假如map各條資料基本上不一樣, 聚合沒什麼意義,做combiner反而畫蛇添足,hive裡也考慮的比較周到通過引數hive.groupby.mapaggr.checkinterval = 100000 (預設)
hive.map.aggr.hash.min.reduction=0.5(預設)
兩個引數的意思是:預先取100000條資料聚合,如果聚合後的條數/100000>0.5,則不再聚合
set hive.groupby.skewindata=true;// 決定
group
by
操作是否支援傾斜的資料。注意:只能對單個欄位聚合.
控制生成兩個MR Job,第一個MR Job Map的輸出結果隨機分配到reduce做次預彙總,減少某些key值條數過多某些key條數過小造成的資料傾斜問題
5、小表與大表關聯
此時,可以通過mapjoin來優化,
set
hive.auto.
convert
.
join
=
true
; //將小表刷入記憶體中
set
hive.mapjoin.smalltable.filesize = 2500000 ;//刷入記憶體表的大小(位元組)
--------------------- 本文來自 百世修行 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/ccorg/article/details/60147863?utm_source=copy