一?數(shù)據(jù)傾斜原理
join實(shí)現(xiàn)原理
sql = select name, orderid
from user t1
join order t2
on t1.uid=t2.uid
group by 實(shí)現(xiàn)原理
sql = select rank, isonline, count(1)
from city
group by 1, 2
數(shù)據(jù)傾斜出現(xiàn)原因
1、對于join過程來說西乖,如果出項(xiàng)較多的key值為空或異常的記錄靡馁,或key值分布不均勻葫隙,就容易出現(xiàn)數(shù)據(jù)傾斜,
2、對于group by 過程來說畔勤,如果某一個(gè)key值有特別的多的記錄,其它key值的記錄比較少,也容易出項(xiàng)數(shù)據(jù)傾斜脉顿。
二?數(shù)據(jù)傾斜的解決方案
join引起數(shù)據(jù)傾斜的解決方法
1、如果是由于key值為空或?yàn)楫惓S涗浀懔龋疫@些記錄不能被過濾掉的情況下艾疟,可以考慮給key賦一個(gè)隨機(jī)值,將這些值分散到不同的reduce進(jìn)行處理。
2蔽莱、如果是一個(gè)大表和一個(gè)小表join的話弟疆,可以考慮使用mapjoin來避免數(shù)據(jù)傾斜,mapjoin的具體過程如下盗冷。分為兩步:
1) 通過mapreduce local task, 掃描小表怠苔,生成為一個(gè)hashtable文件, 并上傳到distributed cache
2) 在map階段,每個(gè)mapper, 從distributed cache中讀取hashtable文件仪糖,掃描大表柑司,并直接在map端join
3)在key值都為有效值時(shí),還可以通過設(shè)置每個(gè)reduce處理的數(shù)據(jù)量的大小來處理數(shù)據(jù)傾斜锅劝,即:
set hive.exec.reducers.bytes.per.reducer = 1000000000或
set mapred.reduce.tasks=800 這兩個(gè)一般不同時(shí)使用攒驰,
另外,還可以設(shè)置下面兩個(gè)參數(shù):
set hive.optimize.skewjoin = true;
set hive.skewjoin.key = skew_key_threshold (default = 100000)
可以就按官方默認(rèn)的1個(gè)reduce 只處理1G 的算法鸠天,那么skew_key_threshold= 1G/平均行長.或者默認(rèn)直接設(shè)成250000000 (差不多算平均行長4個(gè)字節(jié))
group by 引起數(shù)據(jù)傾斜的解決方法
set hive.map.aggr=true讼育,開啟map之后使用combiner,這樣基本上是對各記錄比較同質(zhì)的數(shù)據(jù)效果比較好稠集,相反奶段,則沒有什么意義。通用的做法是設(shè)置下面兩個(gè)參數(shù):
set hive.groupby.mapaggr.checkinterval = 100000 (默認(rèn))執(zhí)行聚合的條數(shù)
set hive.map.aggr.hash.min.reduction=0.5(默認(rèn))如果hash表的容量與輸入行數(shù)之比超過這個(gè)數(shù)剥纷,那么map端的hash聚合將被關(guān)閉痹籍,默認(rèn)是0.5,設(shè)置為1可以保證hash聚合永不被關(guān)閉晦鞋;
還有一個(gè)是set hive.groupby.skewindata=true蹲缠, 這個(gè)只針對單列有效。