在Hive的數(shù)據(jù)處理過程中,由于join造成的傾斜,常見情況是不能做map join的兩個表(能做map join的話基本上可以避免傾斜),其中一個是行為表,另一個應(yīng)該是屬性表。比如我們有三個表,一個用戶屬性表users,一個商品屬性表items,還有一個用戶對商品的操作行為表日志表logs。假設(shè)現(xiàn)在需要將行為表關(guān)聯(lián)用戶表:
select * from logs l join users u on l.user_id = u.user_id;
其中l(wèi)ogs表里面會有一個特殊用戶user_id = 0,代表未登錄用戶,假如這種用戶占了相當(dāng)?shù)谋壤?,那么個別reduce會收到比其他reduce多得多的數(shù)據(jù),因為它要接收所有user_id = 0的記錄進(jìn)行處理,使得其處理效果會非常差,其他reduce都跑完很久了它還在運(yùn)行。
hive給出的解決方案叫skew join,其原理把這種user_id = 0的特殊值先不在reduce端計算掉,而是先寫入hdfs,然后啟動一輪map join專門做這個特殊值的計算,期望能提高計算這部分值的處理速度。當(dāng)然你要告訴hive這個join是個skew join,即:
set hive.optimize.skewjoin = true;
還有要告訴hive如何判斷特殊值,根據(jù)hive.skewjoin.key設(shè)置的數(shù)量hive可以知道,比如默認(rèn)值是100000,那么超過100000條記錄的值就是特殊值。總結(jié)起來,skew join的流程可以用下圖描述:








暫無數(shù)據(jù)