都是HIVE數據傾斜惹的禍

症狀和原因:
  • 操作:join,group by,count distinct 
  • 原因:key分佈不均勻,人爲的建表疏忽,業務數據特點。
  • 症狀:任務進度長時間維持在99%(或100%),查看任務監控頁面,發現只有少量(1個或幾個)reduce子任務未完成;查看未完成的子任務,可以看到本地讀寫數據量積累非常大,通常超過10GB可以認定爲發生數據傾斜。
  • 傾斜度:平均記錄數超過50w且最大記錄數是超過平均記錄數的4倍;最長時長比平均時長超過4分鐘,且最大時長超過平均時長的2倍。
我遇到的問題:
select * from a join b;
1. a表1000多萬,b表不到2億,用mapjoin顯然不行;
2. 設置參數 set hive.groupby.skewindata=true,不起作用;
3. 由於關連鍵爲手機號,自認爲業務數據上不存在數據傾斜;

後來通過查看每個表裏面關聯鍵的分佈,才發現兩個表裏面都存在空串'',而且嚴重傾斜,大表裏面的空串數量有400多萬。
將兩個表的空串過濾後再進行關聯,job時間由原來的40多分鐘減少到2分鐘。

總結:
 1. 數據傾斜的原因就那麼幾種,逐一排查;
 2. 細心,動手,不能光憑感覺來判定;
 3. 判定某一個表的key是否存在數據傾斜,就是group by key,取top N來看;

附:數據傾斜常用解決方法:

1. 萬能膏藥:hive.groupby.skewindata=true
2. 大小表關聯:將key相對分散,並且數據量小的表放在join的左邊,這樣可以有效減少內存溢出錯誤發生的機率;再進一步,可以使用map join讓小的維度表(1000條以下的記錄條數)先迚內存。在map端完成reduce.
3. 大表和大表關聯:把空值的key變成一個字符串加上隨機數,把傾斜的數據分到不同的reduce上,由於null值關聯不上,處理後並不影響最終結果。
4. count distinct大量相同特殊值:count distinct時,將值爲空的情況單獨處理,如果是計算count distinct,可以不用處理,直接過濾,在最後結果中加1。如果還有其他計算,需要進行group by,可以先將值爲空的記錄單獨處理,再和其他計算結果進行union。




當該字段存在大量值爲null或空的記錄,容易發生數據傾斜;


解決思路:
count distinct時,將值爲空的情況單獨處理, 如果是計算 count distinct ,可以不用處理,直接過濾,在最後結果中加1 ;
如果還有其他計算,需要進行group by,可以先將值爲空的記錄單獨處理,再和其他計算結果進行union。

案例:
select count(distinct  end_user_id) as user_num  from trackinfo;
調整爲:
select cast(count(distinct end_user_id)+1 as bigint) as user_num  from trackinfo where  end_user_id is not null and end_user_id <> '';
分析:把爲空的過濾掉,在總的count上加1


Multi-Count Distinct

select pid, count(distinct acookie),count(distinct ip),count(wangwangid ip) from ods_p4ppv_ad_d where dt=20140305 group by pid;
必須設置參數:set hive.groupby.skewindata=true
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章