1. 程式人生 > >hive-資料傾斜解決詳解

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