hive資料傾斜解決方法
Hive的過程中經常會碰到資料傾斜問題,資料傾斜基本都發生在group、join等需要資料shuffle的操作中,這些過程需要按照key值進行資料彙集處理,如果key值過於集中,在彙集過程中大部分資料彙集到一臺機器上,這就會導致資料傾斜。
具體表現為:作業經常reduce完成在99%後一直卡住,最後的1%花了幾個小時都沒有跑完。
常見產生資料傾斜的原因:
#空值產生的資料傾斜
#不同資料型別關聯產生的資料傾斜
#關聯的key非空,但是某個key值大量重複 #distinct、count(distinct)
1、 空值產生的資料傾斜場景:
如日誌中,常會有資訊丟失的問題,比如全網日誌中的user_id,如果取其中的user_id和bmw_users關聯,會碰到資料傾斜的問題。
解決方法1:
user_id為空的不參與關聯
select *
from log a
join bmw_users b
on a.user_id is not null
and a.user_id = b.user_id
union all
select *
from log a
where a.user_id is null;
解決方法2 :
賦與空值分新的key值(推薦)
select *
from logs a
left join bmw_users b
on case when a.user_id is null then concat(‘dp_hive’,rand() )
#把空值的key變成一個字串加上隨機數else a.user_id end = b.user_id;
2、 不同資料型別關聯產生資料傾斜場景:
使用者表中user_id欄位為int,logs表中user_id欄位既有string型別也有int型別。當按照user_id進行兩個表的join操作時,預設的Hash操作會按照int型的id來進行分配,這樣會導致所有string型別的id記錄都分配到同一個reduce中。
解決方法:
把數字型別轉換成字串型別
select *
from users a
left join logs b
on a.user_id = cast(b.user_id as string)
3、關聯的key非空,但是某個key值大量重複
解決方法:
加入隨機數
select a.key as key, b.pv as pv
from(
select key
from table1
where dt='2018-06-18') a
left join(
select key, sum(pv) as pv
from (
select key, round(rand()*1000) as rnd, #加入隨機數,增加併發度
count(1) as pv
from table2
where dt='2018-06-18' group by key,rnd) tmp
group by key) b
on a.key = b.key
4、distinct、count(distinct)
解決方法:
用group by 去重
#distinct替換:
原始sql:
select distinct key from A;
替換後的sql:
select key from A group by key;
#單維度count(distinct)替換
原始sql:
select ship_id, count(distinct order_id) as ship_order_num
from table A
where dt = '2018-06-18'
group by ship_id;
替換後的sql:
select ship_id, count(1) as ship_order_num
from
(select ship_id, order_id
from table A
where dt = '2018-06-18'
group by ship_id, order_id) t
group by ship_id;
#多維度count(distinct)替換 —每個維度單獨處理後關聯