解決資料傾斜,歸根結底是使map的輸出資料更均勻的分布到reduce中去。
1、join
(1)其中乙個表較小,但是key集中。分發到某乙個或幾個reduce上的資料遠高於平均值
(2)大表與大表,但是分桶的判斷欄位0值或空值過多。這些空值都由乙個reduce處理,非常慢
2、group by
group by 維度過小,某值的數量過多。導致處理某值的reduce非常耗時
3、count(distinct)
某特殊值過多,處理此特殊值的reduce耗時
hive.map.aggr=true
map 端部分聚合,相當於combiner
hive.groupby.skewindata=true
由於group by 引起資料傾斜的時候進行負載均衡。當選項設定為 true,生成的查詢計畫會有兩個 mr job。第乙個 mr job 中,map 的輸出結果集合會隨機分布到 reduce 中,每個 reduce 做部分聚合操作,並輸出結果,這樣處理的結果是相同的
group
bykey 有可能被分發到不同的 reduce 中,從而達到負載均衡的目的;第二個 mr job 再根據預處理的資料結果按照 group
bykey 分布到 reduce 中(這個過程可以保證相同的 group
bykey 被分布到同乙個 reduce 中),最後完成最終的聚合操作。
set hive.optimize.skewjoin=true;
如果是join 過程出現傾斜,應該設定為true
(1)空值產生的資料傾斜
場景:如日誌中的user_id有些為空(很多),如果取其中的 user_id 和 使用者表中的user_id 關聯,會碰到資料傾斜的問題。
解決方案1:user_id為空的不參與關聯
select*from
loga
join
users b
on a.user_id
isnot
null
and a.user_id
= b.user_id
union
allselect
*from
loga
where a.user_id
isnull;
解決方案2:賦與空值新的key值(隨機數)
select*from
loga
left
outer
join
users b
oncase
when a.user_id
isnull
then concat(『hive』,rand() ) else a.user_id
end= b.user_id;
結論:方法2比方法1效率更好,不但io少了,而且作業數也少了。解決方法1中 log讀取兩次,jobs是2。解決方法2 job數是1 。這個優化適合無效 id (比如 -99 , 』』, null 等) 產生的傾斜問題。把空值的 key 變成乙個字串加上隨機數,就能把傾斜的資料分到不同的reduce上 ,解決資料傾斜問題。
(2)不同資料型別關聯產生資料傾斜
場景:使用者表中user_id欄位為int,log表中user_id欄位既有string型別也有int型別。當按照user_id進行兩個表的join操作時,預設的hash操作會按int型的id來進行分配,這樣會導致所有string型別id的記錄都分配到乙個reducer中。
解決方案:把數字型別轉換成字串型別
select*from
users a
left
outer
join
logs b
on a.usr_id =
cast(b.user_id
as string)
(3)mapjoin
mapjion會把小表全部讀入記憶體中,在map階段直接拿另外乙個表的資料和記憶體中表資料做匹配,由於在map階段進行了join操作,省去了reduce執行,效率也會高很多。這樣就不會由於資料傾斜導致某個reduce上落資料太多而失敗。
適用條件:關聯操作中有一張表非常小(<1000行)
需要做不等值join操作(a.x < b.y 或者 a.x like b.y等)
例1:關聯操作中有一張表非常小
select f.a, f.b from a t join b f on ( f.a=t.a and f.ftime=20110802
) 該語句中b表有30億行記錄,a表只有100行記錄,而且b表中資料傾斜特別嚴重,有乙個key上有15億行記錄,在執行過程中特別的慢,而且在reduece的過程中遇有記憶體不夠而報錯。
改進:select /*+ mapjoin(a)*/ f.a, f.b from a t join b f on ( f.a=t.a and f.ftime=20110802)
例2:需要做不等值join操作
select a.a, a.b from a join b where a.a>b.a將不等條件寫在where中,那麼mapreduce過程中會進行笛卡爾積,執行效率特別低。
改進:select
/*+ mapjoin(a)
*/ a.a, a.b from a join b where a.a>b.a
例3:小表不小不大
select*from
loga
left
outer
join
users b
on a.user_id
= b.user_id
;users 表有 600w
+ 的記錄,把 users 分發到所有的 map 上也是個不小的開銷,而且 map join 不支援這麼大的小表。如果用普通的 join
,又會碰到資料傾斜的問題。
解決方案:
select
/*+mapjoin(x)*/*
from
loga
left
outer
join
(
select
/*+mapjoin(c)
*/d.*
from ( select
distinct
user_id
from
log) c
join
users d
on c.user_id
= d.user_id
) x
on a.user_id
= b.user_id;
Hive資料傾斜
hive資料傾斜問題 傾斜原因 map輸出資料按key hash分配到reduce中,由於key分布不均勻 或者業務資料本身的特點。等原因造成的reduce上的資料量差異過大。1.1 key分布不均勻 1.2 業務資料本身的特性 1.3 sql語句造成資料傾斜 解決方案 1 引數調節 hive.ma...
hive資料傾斜
key 分布不均勻 業務資料本身的特性 建表考慮不周全 某些 hql 語句本身就存在資料傾斜 1.空值產生的資料傾斜 在日誌中,常會有資訊丟失的問題,比如日誌中的 user id,如果取其中的 user id 和使用者表中的 user id 相關聯,就會碰到資料傾斜的問題。解決方案 1 user i...
hive 資料傾斜介紹
hive在跑資料時經常會出現資料傾斜的情況,使的作業經常reduce完成在99 後一直卡住,最後的 花了幾個小時都沒跑完,這種情況就很可能是資料傾斜的原因,解決方法要根據具體情況來選擇具體的方案 這種情況可以對異常值賦乙個隨機值來分散key 如 selectuserid name fromuser ...