hive優化資料傾斜
hive資料傾斜產⽣的原因
資料傾斜的原因很⼤部分是join傾斜和聚合傾斜兩⼤類
⼀、Hive傾斜之group by聚合傾斜
原因:
分組的維度過少,每個維度的值過多,導致處理某值的reduce耗時很久;
對⼀些型別統計的時候某種型別的資料量特別多,其他的資料型別特別少。當按照型別進⾏group by的時候,會將相同的group by字
段的reduce任務需要的資料拉取到同⼀個節點進⾏聚合,⽽當其中每⼀組的資料量過⼤時,會出現其他組的計算已經完成⽽這個
reduce還沒有計算完成,其他的節點⼀直等待這個節點的任務執⾏完成,所以會⼀直看到map 100% reduce99%的情況;
解決⽅法:
set hive.map.aggr=true;
set hive.groupby.skewindata=true;
原理:
hive.map.aggr=true 這個配置代表開啟map端聚合;
hive.groupby.skewindata=true,當選項設定為true,⽣成的查詢計劃會有兩個MR Job。當第⼀個MR Job中,Map的輸出結果結
合會隨機分佈到Reduce中,每個Reduce做部分聚合操作,並輸出結果。這樣處理的結果是相同的Group By Key有可能被分發到不同
的Reduce中,從⽽達到負載均衡的⽬的。第⼆個MR Job再根據預處理的資料結果按照Group By Key分佈到reduce中,這個過程可
以保證相同的key被分到同⼀個reduce中,最後完成最終的聚合操作。
⼆、Hive傾斜之Map和Reduce優化
原因1:當出現⼩⽂件過多,需要合併⼩⽂件。可以通過set hive.merge.mapredfiles=true來解決;
原因2:輸⼊資料存在⼤塊和⼩塊的嚴重問題,⽐如 說:⼀個⼤⽂件128M,還有1000個⼩⽂件,每 個1KB。 解決⽅法:任務輸⼊
前做⽂件合併,將眾多⼩⽂件合併成⼀個⼤⽂件。通過set hive.merge.mapredfiles=true解決;
原因3:單個⽂件⼤⼩稍稍⼤於配置的block塊的⼤⼩,此時需要適當增加map的個數。解決⽅法:set mapred.map.tasks的個數;
原因4:⽂件⼤⼩適中,但是map端計算量⾮常⼤,如:select id,count(*),sum(case when…),sum(case when …)…需要增加map
個數。解決⽅法:set mapred.map.tasks個數,set mapred.reduce.tasks個數;
三、Hive傾斜之HQL中包含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;
四、Hive傾斜之HQL中join優化
原因:當遇到⼀個⼤表和⼀個⼩表進⾏join操作時。使⽤mapjoin將⼩表載入到記憶體中。如:select /*+ MAPJOIN(a) */ a.c1, b.c1,b.c2 from a join b where a.c1 = b.c1;
遇到需要進⾏join,但是關聯欄位有資料為null,如表⼀的id需要和表⼆的id進⾏關聯;
hive資料傾斜的優化核心思想:
1、減少資料量
利用分割槽或者分桶,不過分桶用的很少,影響資料同步的效率,還有就是列比較多的表,做個裁剪,把列變少
2、避免資料傾斜
簡單的講,資料傾斜就是我們在計算資料的時候,資料的分散度不夠,由於資料分佈不均勻,造成資料大量的集中到一點,造成資料熱點,查詢卡住啦,
比如hivesql裡的distinct、 group By、join就會出現這個現象。
1)一般我會用group by替換distinct,
2)group by的時候把資料量大的分組單獨計算再用union all合併到一起
3)開啟mapjoin
select /* +mapjoin(e)*/ from mydb.emp e;
3、使用一些語句的優化
比如使用with as臨時表啊,group by替換distinct啊等等
4、引數配置優化
之前平臺工程師或者資料組長會配置一些引數,我們開發一般很少配置
5、使用高效的查詢引擎
我們後期使用了sparksql,這個明顯提升了效率啦
6、儲存格式(壓縮)優化
我們還會使用ORC格式,這個對查詢效率也有提升
7、根據業務邏輯對業務實現的整體進行優化
還有就是我們設定合理的分層,讓資料逐步處理