hive的資料傾斜

2022-06-06 22:12:11 字數 3095 閱讀 8628

1.資料傾斜的解決方案

1.1引數調節

hive.map.aggr=true

map 端部分聚合,相當於combiner

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 中),最後完成最終的聚合操作。

2.2sql語句調節

如何join:

關於驅動表的選取,選用join key分布最均勻的表作為驅動表

做好列裁剪和filter操作,以達到兩表做join的時候,資料量相對變小的效果。

大小表join:

使用map join讓小的維度表(1000條以下的記錄條數) 先進記憶體。在map端完成reduce.

大表join大表:

把空值的key變成乙個字串加上隨機數,把傾斜的資料分到不同的reduce上,由於null值關聯不上,處理後並不影響最終結果。

count distinct大量相同特殊值

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

group by維度過小:

採用sum() group by的方式來替換count(distinct)完成計算。

特殊情況特殊處理:

在業務邏輯優化效果的不大情況下,有些時候是可以將傾斜的資料單獨拿出來處理。最後union回去。

2.典型的業務場景

2.1 空值產生的資料傾斜

場景:

如日誌中,常會有資訊丟失的問題,比如日誌中的 user_id,如果取其中的 user_id 和 使用者表中的user_id 關聯,會碰到資料傾斜的問題。

解決方法1:

user_id為空的不參與關聯

select * from

log a

join 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

log a

left outer join users b

on case when a.user_id is

null 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.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)

2.3 小表不小不大怎麼用mapjoin解決傾斜

使用 map join 解決小表(記錄數少)關聯大表的資料傾斜問題,這個方法使用的頻率非常高,但如果小表很大,大到map join會出現bug或異常,這時就需要特別的處理。 以下例子:

select * from

log a

left outer join users b

on a.user_id = b.user_id;

users 表有 600w+ 的記錄,把 users 分發到所有的 map 上也是個不小的開銷,而且 map join 不支援這麼大的小表。如果用普通的 join,又會碰到資料傾斜的問題。

假如,log裡user_id有上百萬個,這就又回到原來map join問題。所幸,每日的會員uv不會太多,有交易的會員不會太多,有點選的會員不會太多,有佣金的會員不會太多等等。所以下面這個方法能解決很多場景下的資料傾斜問題。

解決方法:

select

/*+mapjoin(x)

*/* from

log a

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

) xon 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 資料傾斜

解決資料傾斜,歸根結底是使map的輸出資料更均勻的分布到reduce中去。1 join 1 其中乙個表較小,但是key集中。分發到某乙個或幾個reduce上的資料遠高於平均值 2 大表與大表,但是分桶的判斷欄位0值或空值過多。這些空值都由乙個reduce處理,非常慢 2 group by group...

hive資料傾斜

key 分布不均勻 業務資料本身的特性 建表考慮不周全 某些 hql 語句本身就存在資料傾斜 1.空值產生的資料傾斜 在日誌中,常會有資訊丟失的問題,比如日誌中的 user id,如果取其中的 user id 和使用者表中的 user id 相關聯,就會碰到資料傾斜的問題。解決方案 1 user i...