Hive數(shù)據(jù)傾斜常見問題和解決方案
目錄
前言
一、Explain
二、數(shù)據(jù)傾斜
1.什么是數(shù)據(jù)傾斜?它的主要表現(xiàn)?
2.產(chǎn)生數(shù)據(jù)傾斜的常見原因
一.join時:首先是大表關(guān)聯(lián)小表,容易發(fā)生數(shù)據(jù)傾斜
二.join時:空key過多,或者相同key過多
三.join時:不同數(shù)據(jù)類型關(guān)聯(lián)產(chǎn)生數(shù)據(jù)傾斜
四.join時:大表和不大不小的表聯(lián)接
五.join時:大表聯(lián)接大表
六. 沒有join時:group by發(fā)生的數(shù)據(jù)傾斜
七.沒有join時:count distinct優(yōu)化
八.行列過濾 優(yōu)化?編輯
九、面對復(fù)雜邏輯,每個map耗時較長,適當(dāng)增加map的個數(shù)
十、假如小文件比較多,可以先進(jìn)行小文件合并
十一、調(diào)整reduce個數(shù)
十二、并行執(zhí)行
前言
Hive數(shù)據(jù)傾斜是面試中常問的問題,這里我們需要很熟練地能舉出常見的數(shù)據(jù)傾斜的例子并且給出解決方案。
一、Explain
我們可以通過sql語句前面加expalin來具體查看這條語句的執(zhí)行計劃 通過觀察它的一些參數(shù)來輔助調(diào)優(yōu)
? ?? ??
二、數(shù)據(jù)傾斜
1.什么是數(shù)據(jù)傾斜?它的主要表現(xiàn)?
數(shù)據(jù)傾斜是由于數(shù)據(jù)分布不均勻,造成數(shù)據(jù)大量的集中到一點,造成數(shù)據(jù)熱點的現(xiàn)象。
主要表現(xiàn):任務(wù)進(jìn)度長時間維持在 99%或者 100%的附近,查看任務(wù)監(jiān)控頁面,發(fā)現(xiàn)只有少量 reduce 子任務(wù)未完成,因為其處理的數(shù)據(jù)量和其他的 reduce 差異過大。 單一 reduce 處理的記錄數(shù)和平均記錄數(shù)相差太大,通常達(dá)到好幾倍之多,最長時間遠(yuǎn)大于平均時長。
2.產(chǎn)生數(shù)據(jù)傾斜的常見原因
一.join時:首先是大表關(guān)聯(lián)小表,容易發(fā)生數(shù)據(jù)傾斜
這里Hive自動幫我們把小表放到緩存當(dāng)中了。也就是我們所熟知的mapjoin,在學(xué)習(xí)Hadoop中就已經(jīng)使用過。
以前需要我們手動調(diào):set hive.auto.convert.join=true
一般小表的大小是25M左右,想要改變其大小只需set hive.mapjoin.smalltable.filesize=25000000
以前join的時候小表必須在左邊,現(xiàn)在底層優(yōu)化了,無所謂放到左邊右邊了。
二.join時:空key過多,或者相同key過多
空key可能是異常數(shù)據(jù),兩個表聯(lián)接時,聯(lián)接的字段作為key,可能有很多null值,也可能集中出現(xiàn)在某個值上。這樣就導(dǎo)致了他們經(jīng)過計算得出的哈希值都一樣,然后把它們都放到一個reduce里面,導(dǎo)致這幾個reduce的壓力過大,其他reduce很輕松的場面,也就是我們所謂的數(shù)據(jù)傾斜。
這里我們有兩種常用的解決辦法:第一種是將兩表聯(lián)接之前就去掉這些null值,然后再union all加上是空值的全部數(shù)據(jù)。比如要聯(lián)接user和log:
select * from log a join user b on a.userid is not null and a.userid=b.userid union all select * from log c where c.userid is null;
第二種辦法就是賦予空值新的key值,通過隨機(jī)數(shù)將他們賦給不同的reduce:
這里什么意思呢?就是null現(xiàn)在通過計算不都是一個哈希值嘛,那就給他們賦隨機(jī)數(shù),這樣通過計算就會分配到不同的分區(qū)了。
select * from log a left join user b on case when a.userid is null then concat('hive',rand()) else a.userid end =b.userid;
三.join時:不同數(shù)據(jù)類型關(guān)聯(lián)產(chǎn)生數(shù)據(jù)傾斜
比如兩個表聯(lián)接,聯(lián)接的字段是userid,一個表的userid是string類型,一個表的是int類型,那這樣默認(rèn)按照int來計算哈希的話,那么string類型的都會被分到同一組,易發(fā)生數(shù)據(jù)傾斜。
解決辦法就是把數(shù)字類型 id 轉(zhuǎn)換成 string 類型的 id,或者統(tǒng)一即可。
四.join時:大表和不大不小的表聯(lián)接
如果此時的小表不大不小,不能發(fā)生mapjoin,有什么優(yōu)化方法呢?假如聯(lián)接的字段是userid,這里如果這個“大表”或者“小表”有比較多重復(fù)的userid,那么我們也可以優(yōu)化。
我們這里假設(shè)大表有較多重復(fù)的userid,解決方案就是就是先給“大表”的userid去重然后再聯(lián)接另一個表,此時去重后大表可能會變成小表,這樣又可以mapjoin,查詢完以后再右連接原先的這個大表。比如這時的log表是大表,有很多重復(fù)的userid,users表是小表,但也超過了25M。
select from log a left join (select d* from (select distinct userid from log)c join users d on c.userid=d.userid)x on a.userid=x.userid?
五.join時:大表聯(lián)接大表
兩個大表聯(lián)查,分桶優(yōu)化,根據(jù)id分桶,id是字符型數(shù)值,通過計算哈希值會計算出自己在第幾桶,所以一個桶對應(yīng)一個桶就行,這樣效率提高很多。
一個桶對應(yīng)一個桶,0桶對應(yīng)0桶聯(lián)查,1桶對應(yīng)1桶聯(lián)查...(因為一樣的id肯定在一個對應(yīng)的桶里)
代碼演示:
? ??
? ??
? ?
六. 沒有join時:group by發(fā)生的數(shù)據(jù)傾斜
group by引起的傾斜主要是輸入數(shù)據(jù)行按照group by列分布不均勻引起的。
比如,有個key值有100W個a,此時直接做分組的話,這100W個a將會分到同一個reduce中,這一個節(jié)點處理的數(shù)據(jù)遠(yuǎn)大于其他節(jié)點處理的數(shù)據(jù),造成數(shù)據(jù)傾斜,跑不出數(shù)據(jù)。其原因就是有大量的key集中分配到了同一個reduce,那么我們的解決思路就是將這些key值打散,使起分散到多個reduce節(jié)點處理即可,達(dá)到負(fù)載均衡的效果。解決辦法:(2)可以不動
七.沒有join時:count distinct優(yōu)化
在Hive開發(fā)過程中,應(yīng)該小心使用count distinct,因為很容易引起性能問題,比如下面的SQL:
?select count(distinct userid) from t1;
由于必須去重,因此Hive將會把Map階段的輸出全部分布到一個Reduce Task上,此時很容易引起性能問題。對于這種情況,可以通過先group by再count的方式來優(yōu)化,優(yōu)化后的SQL如下:
select count(*) from (select user from t1 group by userid) a;
其原理為:利用group by去重,再統(tǒng)計group by的行數(shù)目(不過這種方式需要注意數(shù)據(jù)傾斜的問題)。
八.行列過濾 優(yōu)化
謂詞下推?用在SQL優(yōu)化上來說 就是先過濾再做聚合等操作
因為兩個表的關(guān)聯(lián)字段是id?想要在關(guān)聯(lián)以后在用where過濾?實際上底層已經(jīng)優(yōu)化了?關(guān)聯(lián)之前就將兩個表過濾了?但有時候sql寫的長的時候?謂詞下推會失效?所以有點不靠譜的
?(該圖來自知乎)
九、面對復(fù)雜邏輯,每個map耗時較長,適當(dāng)增加map的個數(shù)
十、假如小文件比較多,可以先進(jìn)行小文件合并
十一、調(diào)整reduce個數(shù)
文章來源:http://www.zghlxwxcb.cn/news/detail-780301.html
十二、并行執(zhí)行
?文章來源地址http://www.zghlxwxcb.cn/news/detail-780301.html
總結(jié):Hive數(shù)據(jù)傾斜是非常常見的面試題,基本 可以說出4-6個我覺得就可以應(yīng)付面試?yán)瞺
到了這里,關(guān)于Hive數(shù)據(jù)傾斜常見場景及解決方案(超全?。。。┑奈恼戮徒榻B完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!