MapReduce任務中,Map輸出數據按Key Hash分配到Reduce中,由于Key分布不均勻、業務數據本身的特性、建表時考慮不周、某些SQL語句本身就有數據傾斜等原因造成的reduce上的數據量差異過大,如何將數據均勻的分配到各個Reduce中,就是解決數據傾斜的根本所在,舉三個例子
Map 端聚合
-- 設置如下參數即可開啟map端聚合,就是在Map端將相同的Key先做一次聚合計算,減少往reduce發送的數據
set hive.map.aggr=true
GroupBy 產生的數據傾斜
-- 設置如下參數,在GroupBy時,生成兩個Job,第一個Job給GroupBy的key加隨機數,隨機分布到Reduce中,每個Reduce做
部分聚合操作,先縮小數據量。第二個Job再進行真正的數據處理,完成最終的聚合
set hive.groupby.skewindata = true
count(distinct)
-- count(distinct) 數據傾斜,可以使用 sum + groupby 來完成等價轉換,
-- 原始SQL
select count(distinct uuid) from t1;
-- 等價轉換SQL, 其實就是采用分治思路,我們按照uuid的前n位進行GROUP BY,并做COUNT(DISTINCT )操作,
然后再對所有的COUNT(DISTINCT)結果進行求和
select sum(agg_part) result from
(
select substr(uuid,1,3) uuid_part,
count(distinct substr(uuid,4)) as agg_part
from t1
group by substr(uuid,1,3)
)t