hive數據傾斜的解決辦法

數據傾斜是進行大數據計算時常見的問題。主要分爲map端傾斜和reduce端傾斜,map端傾斜主要是由於輸入文件大小不均勻致使,reduce端主要是partition不均勻致使。html

在hive中遇到數據傾斜的解決辦法:緩存

1、傾斜緣由:map端緩慢,輸入數據文件多,大小不均勻負載均衡

當出現小文件過多,須要合併小文件。能夠經過set hive.merge.mapfiles=true來解決。大數據

set hive.map.aggr=true; //map端部分聚合,至關於Combiner,能夠減少壓力(默認開啓)優化

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

單個文件大小稍稍大於配置的block塊的大寫,此時須要適當增長map的個數。解決方法:set mapred.map.tasks個數code

文件大小適中,但map端計算量很是大,如select id,count(*),sum(case when...),sum(case when...)...須要增長map個數。解決方法:set mapred.map.tasks個數,set mapred.reduce.tasks個數orm

2、當遇到一個大表和一個小表進行join操做時htm

解決方法:小表在join左側,大表在右側,或使用mapjoin 將小表加載到內存中。而後再對比較大的表進行map操做。blog

join就發生在map操做的時候,這裏的join並不會涉及reduce操做。map端join的優點就是在於沒有shuffle,

如:select /*+ MAPJOIN(a) */ 

a.c1, b.c1 ,b.c2 from a join b 

where a.c1 = b.c1; 

3、遇到須要進行join的可是關聯字段有數據爲null,如表一的id須要和表二的id進行關聯,null值的reduce就會落到一個節點上

解決方法1:子查詢中過濾掉null值,id爲空的不參與關聯

解決方法2:用case when給空值分配隨機的key值(字符串+rand())

4、不一樣數據類型關聯產生數據傾斜

場景:一張表s8的日誌,每一個商品一條記錄,要和商品表關聯。但關聯卻碰到傾斜的問題。s8的日誌中有字符串商品id,也有數字的商品id,類型是string的,但商品中的數字id是bigint的。猜想問題的緣由是把s8的商品id轉成數字id作hash來分配reduce,因此字符串id的s8日誌,都到一個reduce上了,解決的方法驗證了這個猜想。

解決方法:把數字類型轉換成字符串類型

Select * from s8_log a

Left outer join r_auction_auctions b

On a.auction_id = cast(b.auction_id as string);

5、當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;

6、join和Group的優化 
2.1 對於普通的join操做,會在map端根據key的hash值,shuffle到某一個reduce上去,在reduce端作join鏈接操做,內存中緩存join左邊的表,遍歷右邊的表,一次作join操做。因此在作join操做時候,將數據量多的表放在join的右邊。 
當數據量比較大,而且key分佈不均勻,大量的key都shuffle到一個reduce上了,就出現了數據的傾斜。 

在map端產生join

         mapJoin的主要意思就是,當連接的兩個表是一個比較小的表和一個特別大的表的時候,咱們把比較小的table直接放到內存中去,而後再對比較大的表格進行map操做。join就發生在map操做的時候,每當掃描一個大的table中的數據,就要去去查看小表的數據,哪條與之相符,繼而進行鏈接。這裏的join並不會涉及reduce操做。map端join的優點就是在於沒有shuffle,


2.2 對於Group操做,首先在map端聚合,最後在reduce端坐聚合,hive默認是這樣的,如下是相關的參數 
· hive.map.aggr = true是否在 Map 端進行聚合,默認爲 True 
· hive.groupby.mapaggr.checkinterval = 100000在 Map 端進行聚合操做的條目數目

轉載自:https://www.cnblogs.com/kongcong/p/7777092.html

相關文章
相關標籤/搜索