MapReduce如何解決數據傾斜?
首先要定位到哪些數據 導致數據傾斜。確定完之後常見的處理方法有:
1. 在加個combiner函數,加上combiner相當於提前進行reduce,就會把一個mapper中的相同key進行了聚合,減少shuffle過程中數據量,以及reduce端的計算量。這種方法可以有效的緩解數據傾斜問題,但是如果導致數據傾斜的key 大量分布在不同的mapper的時候,這種方法就不是很有效了。
2. 局部聚合加全局聚合。第二種方法進行兩次mapreduce,第一次在map階段對那些導致了數據傾斜的key 加上1-n的隨機前綴,這樣之前相同的key 也會被分到不同的reduce中,進行聚合,這樣的話就有那些傾斜的key進行局部聚合,數量就會大大降低。然後再進行第二次mapreduce這樣的話就去掉隨機前綴,進行全局聚合。這樣就可以有效地降低mapreduce了。不過進行兩次mapreduce,性能稍微比一次的差些。
自己的想法,還請大家多多討論,看看有沒有更好的方法
2017-10-23 細柳條 小秀才翻譯鋪
前言:數據傾斜是日常大數據查詢中隱形的一個BUG,遇不到它時你覺得數據傾斜也就是書本博客上的一個無病呻吟的偶然案例,但當你遇到它是你就會懊悔當初怎麼不多了解一下這個赫赫有名的事故。
當然你和數據傾斜的緣分深淺還是看你公司的業務邏輯和數據量有沒有步入數據傾斜的領地。
說明:關於數據傾斜的產生原因我將結合 map 和 reduce 階段中的 shuffle 來講解,若是對 shuffle 有所忘記需要溫故的請到 MapReduce:詳解Shuffle(copy,sort,merge)過程 進行相關了解。另本人能力有限,僅根據自己所了解的知識回答,若有誤處或不足之處望不吝指出。
一、什麼是數據傾斜以及數據傾斜是怎麼產生的?
簡單來說數據傾斜就是數據的key 的分化嚴重不均,造成一部分數據很多,一部分數據很少的局面。
舉個 word count 的入門例子,它的map 階段就是形成 (「aaa」,1)的形式,然後在reduce 階段進行 value 相加,得出 「aaa」 出現的次數。若進行 word count 的文本有100G,其中 80G 全部是 「aaa」 剩下 20G 是其餘單詞,那就會形成 80G 的數據量交給一個 reduce 進行相加,其餘 20G 根據 key 不同分散到不同 reduce 進行相加的情況。如此就造成了數據傾斜,臨床反應就是 reduce 跑到 99%然後一直在原地等著 那80G 的reduce 跑完。
簡化了的 shuffle 圖就是這樣。
這樣就能清楚看到,數據經過 map後,由於不同key 的數據量分布不均,在shuffle 階段中通過 partition 將相同的 key 的數據打上發往同一個 reducer 的標記,然後開始 spill (溢寫)寫入磁碟,最後merge成最終map階段輸出文件。
如此一來 80G 的 aaa 將發往同一個 reducer ,由此就可以知道 reduce 最後 1% 的工作在等什麼了。
二、為什麼說數據傾斜與業務邏輯和數據量有關?
從另外角度看數據傾斜,其本質還是在單台節點在執行那一部分數據reduce任務的時候,由於數據量大,跑不動,造成任務卡住。若是這台節點機器內存夠大,CPU、網路等資源充足,跑 80G 左右的數據量和跑10M 數據量所耗時間不是很大差距,那麼也就不存在問題,傾斜就傾斜吧,反正機器跑的動。所以機器配置和數據量存在一個合理的比例,一旦數據量遠超機器的極限,那麼不管每個key的數據如何分布,總會有一個key的數據量超出機器的能力,造成 reduce 緩慢甚至卡頓。
業務邏輯造成的數據傾斜會多很多,日常使用過程中,容易造成數據傾斜的原因可以歸納為幾點,有前輩早就整理好,我就搬磚了:
分組 註:group by 優於distinct group
情形:group by 維度過小,某值的數量過多後果:處理某值的reduce非常耗時去重 distinct count(distinct xx)情形:某特殊值過多後果:處理此特殊值的reduce耗時連接 join
情形1:其中一個表較小,但是key集中後果1:分發到某一個或幾個Reduce上的數據遠高於平均值情形2:大表與大表,但是分桶的判斷欄位0值或空值過多後果2:這些空值都由一個reduce處理,非常慢三、如何處理數據傾斜問題呢?
1、調優參數
set hive.map.aggr=true;
set hive.groupby.skewindata=true;
好多同學使用這兩個參數的次數真的很多,但是他們不了解這兩個參數是怎麼解決數據傾斜的,從哪個角度著手的。
hive.map.aggr=true:在map中會做部分聚集操作,效率更高但需要更多的內存。
hive.groupby.skewindata=true:數據傾斜時負載均衡,當選項設定為true,生成的查詢計劃會有兩個MRJob。第一個MRJob 中,Map的輸出結果集合會隨機分布到Reduce中,每個Reduce做部分聚合操作,並輸出結果,這樣處理的結果是相同的GroupBy Key有可能被分發到不同的Reduce中,從而達到負載均衡的目的;第二個MRJob再根據預處理的數據結果按照GroupBy Key分布到Reduce中(這個過程可以保證相同的GroupBy Key被分布到同一個Reduce中),最後完成最終的聚合操作。
由上面可以看出起到至關重要的作用的其實是第二個參數的設置,它使計算變成了兩個mapreduce,先在第一個中在 shuffle 過程 partition 時隨機給 key 打標記,使每個key 隨機均勻分布到各個 reduce 上計算,但是這樣只能完成部分計算,因為相同key沒有分配到相同reduce上,所以需要第二次的mapreduce,這次就回歸正常 shuffle,但是數據分布不均勻的問題在第一次mapreduce已經有了很大的改善,因此基本解決數據傾斜。
2、在 key 上面做文章,在 map 階段將造成傾斜的key 先分成多組,例如 aaa 這個 key,map 時隨機在 aaa 後面加上 1,2,3,4 這四個數字之一,把 key 先分成四組,先進行一次運算,之後再恢復 key 進行最終運算。
3、能先進行 group 操作的時候先進行 group 操作,把 key 先進行一次 reduce,之後再進行 count 或者 distinct count 操作。
4、join 操作中,使用 map join 在 map 端就先進行 join ,免得到reduce 時卡住。
以上4中方式,都是根據數據傾斜形成的原因進行的一些變化。要麼將 reduce 端的隱患在 map 端就解決,要麼就是對 key 的操作,以減緩reduce 的壓力。總之了解了原因再去尋找解決之道就相對思路多了些,方法肯定不止這4種。
四、總結
數據key分布不均的問題導致了之後一系列變化,如何使最後的結果變得有利,那就得先了解過程,然後自己引導變化使它朝有利的方向走去。
推薦閱讀:
※國內較知名的大數據服務平台有哪幾家?
※大數據會否使計劃經濟最終掌控世界?
※如今大數據交易平台和大數據交易所有很多,如何解決數據的歸屬權,數據的定價以及交付方式?
※岩土工程/土木工程怎樣應用大數據?