hive資料傾斜
group by 中的計算均衡優化
1.map端部分聚合
先看看下面這條sql,由於使用者的性別只有男和女兩個值 (未知)。如果沒有map端的部分聚合優化,map直接把groupby_key 當作reduce_key傳送給reduce做聚合,就會導致計算不均衡的現象。雖然map有100萬個,但是reduce只有兩個在做聚合,每個reduce處理100億條記錄。
selectuser.gender,count(1) from user group by user.gende
沒開map端聚合產生的計算不均衡現象
hive.map.aggr=true引數控制在group by的時候是否map區域性聚合,這個引數預設是開啟的。引數開啟後的計算過程如下圖。由於map端已經做了區域性聚合,雖然還是只有兩個reduce做最後的聚合,但是每個reduce只用處理100萬行記錄,相對優化前的100億小了1萬
map端聚合開啟map聚合開關預設是開啟的,但是不是所有的聚合都需要這個優化。考慮先面的sql,如果groupby_key是使用者id,因為使用者id沒有重複的,因此map聚合沒有太大意義,並且浪費資源。
select user..id,count(1) from user group by user.id
hive.groupby.mapaggr.checkinterval = 100000
hive.map.aggr.hash.min.reduction=0.5
資料傾斜
通常這種情況都是在有distinct出現的時候,比如下面的sql,由於map需要儲存所有的user.id
,map聚合開關會自動關掉,導致出現計算不均衡的現象,只有2個redcue做聚合,每個reduce處理100億條記錄。
select user.gender,count(distinct user.id
) from user group by user.gender
) from user group by user.gender
hive.groupby.skewindata =true
引數會把上面的sql翻譯成兩個mr,第乙個mr的reduce_key是gender+id。因為id是乙個隨機雜湊的值,因此這個mr的reduce計算是很均勻的,reduce完成區域性聚合的工作
mr1第二個mr完成最終的聚合,統計男女的distinct id值,資料流如下圖所示,每個map只輸出兩條記錄,因此雖然只有兩個redcue計算也沒有關係,絕大部分計算量已經在第乙個mr完成
mr2 hive.groupby.skewindata
預設是關閉的,因此如果確定有不均衡的情況,需要手動開啟這個開關。當然,並不是所有的有distinct的group by都需要開啟這個開關,比如下面的
sql。因為user.id
select id,count (distinct gender) from user group by user.id
select gender,count (distinct id) from user group by user.gender
是乙個雜湊的值,因此已經是計算均衡的了,所有的reduce都會均勻計算。只有在groupby_key不雜湊,而distinct_key雜湊的情況下才需要開啟這個開關,其他的情況map聚合優化就足矣。
;三.join 中的計算均衡優化在hive中,join操作一般都是在reduce階段完成的,寫sql的時候要注意把小表放在join的左邊,原因是在 join 操作的 reduce 階段,位於 join 操作符左邊的表的內容會被載入進記憶體,將條目少的表放在左邊,可以有效減少發生 out of memory 錯誤的機率。 乙個大表和乙個配置表的reduce join經常會引起計算不均衡的情況。比如配置表gender_config(gender string,gender_id int)。把「男」「女」字串對映成乙個id。配置表和上面的user表join的sql如下: select user.id
gender_config.gender_id from gender_config join user on gender_config.gender=user.gender gender 只有男女兩個值,hive處理join的時候把join_key作為reduce_key,因此會出現和group by類似的reduce計算不均衡現象,只有兩個reduce參與計算,每個reduce計算100億條記錄。
乙個大表和乙個小配置表的reduce join流程圖 這種大表和配置表通常採用mapjoin的方式來解決這種不均衡的現象。目前hive是採用/*+ mapjoin(gender_config) */提示的方式告訴翻譯器把sql翻譯成mapjoin,提示裡必須指明配置表是哪個。 select /*+ mapjoin(gender_config) */ user.id
gender_config.gender_id from gender_config join user on gender_config.gender=user.gender
Hive優化 資料傾斜 典型案例
優化 1 fetch抓取 hive.fetch.task.conversion 設定成 more 執行一些limit,select 單個字段不會跑mr程式 2 本地模式 hive.exec.mode.local.auto 的值為 true 3 表的優化 3.1 老版本hive,把資料小的表放在joi...
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...