為何會發生數據傾斜?
19世紀末意大利經濟學家帕累托發現在任何一組東西中,最重要的只占其中一小部分,約20%,其余80%盡管是多數,卻是次要的,因此又稱二八定律,又叫帕累托法則。
因此,正常的數據分布理論上來說都是會發生傾斜的,例如,在進行運維大數據分析時,80%的故障異常都是由20%的常見運維問題導致的,因此,會導致少數的問題有非常多的記錄。
數據傾斜產生原因:
MapReduce模型中,數據傾斜問題是很常見的,因為同一個Key的Values,在進行groupByKey、countByKey、reduceByKey、join等操作時一定是分配到某一個節點上的一個Task中進行處理的,如果某個Key對應的數據量特別大的話,就會造成某個節點的堵塞甚至宕機的情況。在并行計算的作業中,整個作業的進度是由運行時間最長的那個Task決定的,在出現數據傾斜時,整個作業的運行將會非常緩慢,甚至會發生OOM異常。
解決方案
一、使用Hive ETL(提取、轉換和加載) 預處理數據
Spark作業數據通常來源于Hive中,如果發生傾斜的數據來源于Hive表,可以通過Hive來進行數據預處理。直接通過Hive ETL,對數據預先進行聚合或join等操作,直接生成結果數據表,這樣在Spark作業中針對的數據源就是預處理過后的Hive表,就不需要再去執行Shuffle類的算子了,從根源上解決了數據傾斜。
但是,因為數據本身就存在著分布不均的問題,所以在Hive ETL進行數據處理時,還是會發生數據傾斜,作業速度變慢的問題,這種解決方案只是避免的Spark作業時的數據傾斜問題。
二、提高Reduce任務的并行度
將Reduce Task的數量變多,就可以讓每個Reduce Task分配到更少的數據量,這樣可以緩解數據傾斜的問題。
在調用groupByKey、countByKey、reduceByKey時,傳入Reduce端的并行度參數,這樣在進行Shuffle操作時,會創建指定的Reduce Task,可以讓每個Reduce Task分配到更少量的數據,避免了Spark作業時OOM的情況。
三、使用隨機Key進行分步聚合
在groupByKey、reduceByKey操作時,第一次聚合的時候,對Key加一個隨機前綴,例如10以內的隨機數,將Key進行打散操作,將Key分為多組后,先進行局部聚合,在第二次聚合的時候,去除掉每個Key的前綴,再所有Key進行全局的聚合。
四、使用廣播數據避免Reduce操作
當兩個RDD要進行join操作時,其中一個RDD是比較小的,將較小的那個RDD進行Broadcast操作后,不使用join進行兩個RDD的連接,因為普通的join操作是會觸發Shuffle過程的,一旦觸發Shuffle會將相同Key的數據都拉取到同一個Task中進行處理,而使用map join從廣播變量中獲取較小的RDD中的數據進行連接操作,不會觸發Shuffle,避免了數據傾斜的發生。
但是,如果兩個RDD都比較大,將其中一個RDD的數據進行Broadcast后,數據將會在每個Executor的Block Manger中都駐留一份,很有可能導致內存溢出,程序崩潰。
五、將發生數據傾斜的key單獨進行join
首先通過Spark中的sample算子對數據進行隨機抽樣,然后對抽樣出的數據中Key出現的次數進行排序,這樣就可以找到導致數據傾斜的一個或多個Key,然后對數據進行Filter操作,可以將產生數據傾斜的Key和普通Key的數據分離,生成兩個RDD。
對于可能產生數據傾斜的RDD,給每條數據都打上隨機數進行打散操作后,再去進行join,然后去除前綴后再跟普通RDD進行join后的結果,進行union操作。
這種方案只需要針對數據中有少量導致數據傾斜的Key,如果導致數據傾斜的Key特別多,則不適用。
六、使用隨機數和擴容表進行join
若在join操作時,RDD中有大量的Key導致了數據傾斜,可以考慮選擇一個RDD進行擴容,將每條數據映射為多條數據,每條數據都帶有0~n的前綴。另一個RDD的每條數據都打上一個n以內的隨機值前綴。然后,將兩個RDD進行join操作后,再去掉前綴。
此方案與方案五的區別在于,當有大量導致數據傾斜Key的情況時,沒法將部分Key拆分出來單獨處理,因此只能對整個RDD 進行數據擴容,對資源要求很高。
總結
方案1使用Hive進行數據預處理,適用于對Spark作業執行性能要求較高的場景,將數據傾斜在Hive ETL中解決,只有在Hive ETL周期性處理數據時作業速度較慢,其余的每次Spark作業速度都將很快;
方案2提高Reduce任務的并行度,指標不治本,因為,沒有從根本上改變數據傾斜的本質和問題,只是緩解了執行Reduce Task時的壓力;
方案3使用隨機Key進行分步聚合,適用于groupByKey、reduceByKey等聚合類的操作;
方案4、5、6都是針對于join操作時發生的數據傾斜,方案4使用廣播數據避免Reduce操作適用于其中一個RDD是比較小的情況,方案5將發生數據傾斜的key單獨進行join適用于少量數據傾斜是由少量的Key導致的,方案6使用隨機數和擴容表進行join對資源要求很高,適用于大量的Key導致了數據傾斜。
本文鏈接:http://www.avtobanya.com/37101.html
網友評論comments