1. 程式人生 > >hive 資料傾斜的常見處理方式

hive 資料傾斜的常見處理方式

1.什麼是資料傾斜?

資料傾斜主要表現在,map /reduce程式執行時,reduce節點大部分執行完畢,但是有一個或者幾個reduce節點執行很慢,導致整個程式的處理時間很長,這是因為某一個key的條數比其他key多很多(有時是百倍或者千倍之多),這條key所在的reduce節點所處理的資料量比其他節點就大很多,從而導致某幾個節點遲遲執行不完。

2.常見容易出現數據傾斜的操作?

  資料傾斜可能會發生在group過程和join過程。  

1.大表和小表關聯時

     比如,一個上千萬行的記錄表和一個幾千行表之間join關聯時,容易發生資料傾斜。為什麼大表和小表容易發生資料傾斜(無非有的reduce執行時間被延遲)?請參考

Hive中小表與大表關聯(join)的效能分析

解決方式:

1.多表關聯時,將小表(關聯鍵記錄少的表)依次放到前面,這樣可以觸發reduce端更少的操作次數,減少執行時間。

 2.同時可以使用Map Join讓小的維度表快取到記憶體。在map端完成join過程,從而省略掉redcue端的工作。但是使用這個功能,需要開啟map-side join的設定屬性:set hive.auto.convert.join=true(預設是false)

同時還可以設定使用這個優化的小表的大小:set hive.mapjoin.smalltable.filesize=25000000(預設值25M)

2.大表和大表的關聯

1.比如:大表與大表關聯,但是其中一張表的多是空值或者0比較多,容易shuffle給一個reduce,造成執行慢

解決方式1:

1.這種情況可以對異常值賦一個隨機值來分散key,均勻分配給多個reduce去執行,比如:

 
  1. select ...忽略......

  2.  
  3. from trackinfo a left outer join pm_info b

  4.  
  5. on ( case when (a.ext_field7 is not null and length(a.ext_field7) > 0 and a.ext_field7 rlike '^[0-9]+$')

  6.  
  7. then cast(a.ext_field7 as bigint)

  8.  
  9. else cast(ceiling(rand() * -65535) as bigint) end = b.id )

  10.  
  11. #將A表垃圾資料(為null,為0,以及其他型別的資料)賦一個隨機的負數,然後將這些資料shuffle到不同reduce處理。

解決方式2:

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.其他情況資料傾斜的處理

1.比如因group by造成資料傾斜?使用Hive對資料做一些型別統計的時候遇到過某種型別的資料量特別多,而其他型別資料的資料量特別少。當按照型別進行group by的時候,會將相同的group by欄位的reduce任務需要的資料拉取到同一個節點進行聚合,而當其中每一組的資料量過大時,會出現其他組的計算已經完成而這裡還沒計算完成,其他節點的一直等待這個節點的任務執行完成,所以會看到一直map 100%  reduce 99%的情況。

解決方式1:

hive.map.aggr=true  (預設true) 這個配置項代表是否在map端進行聚合,相當於Combiner

hive.groupby.skewindata=true(預設false)

有資料傾斜的時候進行負載均衡,當選項設定為 true,生成的查詢計劃會有兩個 MR Job。第一個 MR Job 中,Map 的輸出結果集合會隨機分佈到 Reduce 中,每個 Reduce 做部分聚合操作,並輸出結果,這樣處理的結果是相同的 Group By Key 有可能被分發到不同的 Reduce 中,從而達到負載均衡的目的;第二個 MR Job 再根據預處理的資料結果按照 Group By Key 分佈到 Reduce 中(這個過程可以保證相同的 Group By Key 被分佈到同一個 Reduce 中),最後完成最終的聚合操作

4.通用的一些資料傾斜的處理方法

1.reduce個數太少

reduce數太少set mapred.reduce.tasks=800;

預設是先設定hive.exec.reducers.bytes.per.reducer這個引數,設定了後hive會自動計算reduce的個數,因此兩個引數一般不同時使用

2.當HiveQL中包含count(distinct)時

   如果資料量非常大,執行如select a,count(distinct b) from t group by a;型別的SQL時,會出現資料傾斜的問題。

   解決方法:使用sum...group by代替。如select a,sum(1) from (select a, b from t group by a,b) group by a;

--------------------- 本文來自 alirobot 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/qq_26442553/article/details/80866723?utm_source=copy