本人部落格為日常筆記直接貼上,未整理排版,可參考相似內容的部落格。
hive學習之路 (十九)hive的資料傾斜
hive面試常問:
hq語句
優化sort by order by distribute by
分割槽表 分桶表的區別
內部表 外部表的區別
資料傾斜:資料分布不均勻
hive底層的執行引擎 mr:mapreduce 由兩部分組成:map 、 reduce
歸根結底:底層mr的資料傾斜。
map端:乙個maptask處理乙個切片split,不會相差太大。
reduce端:處理所有map的輸出結果。reduce端的並行度:結點個數*0.95 。資料量特別大時,reduce端的並行度不高,很容易產生資料傾斜。
怎麼判斷程式發生了資料傾斜?
reduce停留在乙個階段很長時間不動。(如下例,一直停留在30%)
2019-06-25 17:39:34,801 stage-1 map = 0%, reduce = 0%
2019-06-25 17:39:34,801 stage-1 map = 50%, reduce = 0%
2019-06-25 17:39:34,801 stage-1 map = 75%, reduce = 0%
2019-06-25 17:39:45,661 stage-1 map = 100%, reduce = 0%, cumulative cpu 2.76 sec
2019-06-25 17:39:45,661 stage-1 map = 100%, reduce = 10%, cumulative cpu 2.76 sec
2019-06-25 17:39:45,661 stage-1 map = 100%, reduce = 20%, cumulative cpu 2.76 sec
2019-06-25 17:39:45,661 stage-1 map = 100%, reduce = 30%, cumulative cpu 2.76 sec
2019-06-25 17:39:45,661 stage-1 map = 100%, reduce = 30%, cumulative cpu 2.76 sec
2019-06-25 17:39:45,661 stage-1 map = 100%, reduce = 30%, cumulative cpu 2.76 sec
2019-06-25 17:39:45,661 stage-1 map = 100%, reduce = 30%, cumulative cpu 2.76 sec
2019-06-25 17:39:45,661 stage-1 map = 100%, reduce = 30%, cumulative cpu 2.76 sec
2019-06-25 17:40:03,198 stage-1 map = 100%, reduce = 100%, cumulative cpu 8.55 sec
資料傾斜與 1)資料量; 2)map端key的設定;有關
hive中哪些操作容易造成資料傾斜:
join操作:
join關聯時有null值
select a.,b. from a join b on a.id = b.id;
日誌資料,a.id許多null值,所有null值最終都會到同乙個分割槽中,null值特別多,會造成有null關聯的那個分割槽資料特別多。
如何解決:
1) null值不參與關聯,單獨進行union all
select *
from user join log on user.id = log.userid and log.userid is not null
union all
select *
from log
where userid is null
2)給null值加乙個隨機數,雜湊null
null — null123
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上 ,解決資料傾斜問題。
關聯時資料型別不同
場景:使用者表中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)
小表 關聯 大表 造成資料傾斜
這個join到底是map端的join還是reduce端的join
map端的join效率高 並行度高 不容易產生資料傾斜
map端的join擅長大小表關聯
set hive.auto.convert.join = true; //設定mapjoin優化自動開啟
//在設定map端join的小表的大小,只要小表的大小不超過這個值,預設都走map端的join
set hive.mapjoin.smalltable.filesize = 25000000
在進行關聯操作的時候,兩個表就類似於mr程式中 fileinputformat.addinputpaths()
就可以獲取資料的長度—大小 如果兩個表中最小表的大小不超過25m大小 缺省會把小表放在快取中 走mapjoin 如果最小表大於設定的值 預設走reduce端的join
大表*大表關聯
切分其中乙個大表 一對多 切分多的表大小25m
表a:26m 表b:1g 預設走reduce端的jooin 這個時候可以強制走map端的join
select
/*+mapjoin(a)*/ #強制執行map端的join ()中代表需要載入到快取中的資料
a.*,b.* from a join b on a.id = b.id;
map端的join:
首先將小表載入到快取中, join.addcachefile()
在setup中讀取快取中的資料放在容器中
在map端進行關聯 不需要reduce
Hive 資料傾斜原因及解決方法彙總
1 資料傾斜根本原因 由於資料分布不均勻,導致map端讀取的資料分布不均勻 資料長尾分布 從而使得map處理的資料量差異過大。2 解決思路 hive是分階段執行的,map處理資料量的差異取決於上乙個stage的reduce輸出,所以解決的根本方法就是如何將資料均勻的分布到各個reduce中 3 出現...
Hive資料傾斜解決方法總結
資料傾斜是進行大資料計算時最經常遇到的問題之一。當我們在執行hiveql或者執行mapreduce作業時候,如果遇到一直卡在map100 reduce99 一般就是遇到了資料傾斜的問題。資料傾斜其實是進行分布式計算的時候,某些節點的計算能力比較強或者需要計算的資料比較少,早早執行完了,某些節點計算的...
Hive資料傾斜解決方法總結
資料傾斜是進行大資料計算時最經常遇到的問題之一。當我們在執行hiveql或者執行mapreduce作業時候,如果遇到一直卡在map100 reduce99 一般就是遇到了資料傾斜的問題。資料傾斜其實是進行分布式計算的時候,某些節點的計算能力比較強或者需要計算的資料比較少,早早執行完了,某些節點計算的...