數(shù)據(jù)傾斜就是由于數(shù)據(jù)分布不均勻含友,數(shù)據(jù)大量集中到一點上,造成數(shù)據(jù)熱點压昼。大多數(shù)情況下,分為一下三種情況:
1.map端執(zhí)行比較快侠草,reduce執(zhí)行很慢,因為partition造成的數(shù)據(jù)傾斜犁嗅。
2.某些reduce很快边涕,某些reduce很慢,也是因為partition造成的數(shù)據(jù)傾斜褂微。?
3.某些map執(zhí)行很快功蜓,某些map執(zhí)行很慢,這是因為數(shù)據(jù)本身的分布的不合理性造成的宠蚂。?
造成上面reduce和map任務(wù)運(yùn)行很緩慢本質(zhì)上就兩種情況:
第一:reduce緩慢是因為partition造成滴式撼;
第二:map端緩慢是因為數(shù)據(jù)本身的分布不合理性。
下面介紹map緩慢和reduce緩慢
Reduce端緩慢:兩個table的join操作會造成數(shù)據(jù)傾斜肥矢,會造成reduce緩慢端衰,這個相對比較好解決叠洗,我們不是有三種解決join性能的方案嗎甘改?mapjoin,common join灭抑,smbJoin可以解決數(shù)據(jù)傾斜十艾。另外,有些情況下造成的reduce緩慢無法解決腾节,因為數(shù)據(jù)本身也不是服從均勻分布忘嫉。大多數(shù)還是高斯分布荤牍。
reduce性能本質(zhì)上是由于groupby操作導(dǎo)致的,而count(distinct)內(nèi)部本質(zhì)也是有g(shù)roupby實現(xiàn)
map端緩慢:這種情況是由于每條數(shù)據(jù)的相對位置造成的庆冕。有兩種方案:
第一:設(shè)置在map端聚合康吵,set hive.map.aggr=true 可以減小壓力(默認(rèn)開啟)
第二:可以set hive.groupby.skewindata=true(默認(rèn)關(guān)閉),此時hive的執(zhí)行在MR后臺會存在兩個map一個reduce访递,第一個map本質(zhì)上就是先對數(shù)據(jù)進(jìn)行shuffle晦嵌,第二個map就可以對shuffle之后的數(shù)據(jù)進(jìn)行操作。
join和Group的優(yōu)化
2.1 對于普通的join操作拷姿,會在map端根據(jù)key的hash值惭载,shuffle到某一個reduce上去,在reduce端做join連接操作响巢,內(nèi)存中緩存join左邊的表描滔,遍歷右邊的表,一次做join操作踪古。所以在做join操作時候含长,將數(shù)據(jù)量多的表放在join的右邊。
當(dāng)數(shù)據(jù)量比較大伏穆,并且key分布不均勻茎芋,大量的key都shuffle到一個reduce上了,就出現(xiàn)了數(shù)據(jù)的傾斜蜈出。
在map端產(chǎn)生join
? ? ? ? ?mapJoin的主要意思就是田弥,當(dāng)鏈接的兩個表是一個比較小的表和一個特別大的表的時候,我們把比較小的table直接放到內(nèi)存中去铡原,然后再對比較大的表格進(jìn)行map操作偷厦。join就發(fā)生在map操作的時候,每當(dāng)掃描一個大的table中的數(shù)據(jù)燕刻,就要去去查看小表的數(shù)據(jù)只泼,哪條與之相符,繼而進(jìn)行連接卵洗。這里的join并不會涉及reduce操作请唱。map端join的優(yōu)勢就是在于沒有shuffle,
2.2 對于Group操作过蹂,首先在map端聚合十绑,最后在reduce端坐聚合,hive默認(rèn)是這樣的酷勺,以下是相關(guān)的參數(shù)
· hive.map.aggr = true是否在 Map 端進(jìn)行聚合本橙,默認(rèn)為 True
· hive.groupby.mapaggr.checkinterval = 100000在 Map 端進(jìn)行聚合操作的條目數(shù)目
當(dāng)然有的hive操作,不存在數(shù)據(jù)傾斜的問題脆诉,比如數(shù)據(jù)聚合類的操作甚亭,像sum贷币、count,因為已經(jīng)在map端做了聚合操作了亏狰,到reduce端的數(shù)據(jù)相對少一些役纹,所以不存在這個問題。
空值數(shù)據(jù)傾斜
場景:如日志中暇唾,常會有信息丟失的問題字管,比如全網(wǎng)日志中的user_id,如果取其中的user_id和bmw_users關(guān)聯(lián)信不,會碰到數(shù)據(jù)傾斜的問題嘲叔。
解決方法1:?user_id為空的不參與關(guān)聯(lián)
解決方法2?:賦與空值分新的key值
不同數(shù)據(jù)類型關(guān)聯(lián)產(chǎn)生數(shù)據(jù)傾斜
場景:一張表s8的日志,每個商品一條記錄抽活,要和商品表關(guān)聯(lián)硫戈。但關(guān)聯(lián)卻碰到傾斜的問題。s8的日志中有字符串商品id,也有數(shù)字的商品id,類型是string的下硕,但商品中的數(shù)字id是bigint的丁逝。猜測問題的原因是把s8的商品id轉(zhuǎn)成數(shù)字id做hash來分配reduce,所以字符串id的s8日志梭姓,都到一個reduce上了霜幼,解決的方法驗證了這個猜測。
解決方法:把數(shù)字類型轉(zhuǎn)換成字符串類型