Spark數據傾斜
-
產生原因
首先RDD的邏輯其實時表示一個對象集合。在物理執行期間,RDD會被分為一系列的分區,每個分區都是整個數據集的子集。當spark調度並運行任務的時候,Spark會為每一個分區中的數據創建一個任務。大部分的任務處理的數據量差不多,但是有少部分的任務處理的數據量很大,因而Spark作業會看起來運行的十分的慢,從而產生數據傾斜(進行shuffle的時候)。
數據傾斜只會發生在shuffle過程中。這里給大家羅列一些常用的並且可能會觸發shuffle操作的算子:distinct、groupByKey、reduceByKey、aggregateByKey、join、cogroup、repartition等。出現數據傾斜時,可能就是你的代碼中使用了這些算子中的某一個所導致的。例子:
多個key對應的values,比如一共是90萬。可能某個key對應了88萬數據,被分配到一個task上去面去執行。另外兩個task,可能各分配到了1萬數據,可能是數百個key,對應的1萬條數據。這樣就會出現數據傾斜問題。 -
解決方法
(1):數據混洗的時候,使用參數的方式為混洗后的RDD指定並行度實現原理:提高shuffle操作的並行度,增加shuffle read task的數量,可以讓原本分配給一個task的多個key分配給多個task,從而讓每個task處理比原來更少的數據,舉例來說,如果原本有5個key,每個key對應10條數據,這5個key都是分配給一個task的,那么這個task就要處理50條數據。而增加了shuffle read task以后,每個task就分配到一個key,即每個task就處理10條數據,那么自然每個task的執行時間都會變短了(很簡單,主要給我們所有的shuffle算子,比如groupByKey、countByKey、reduceByKey。在調用的時候,傳入進去一個參數。那個數字,就代表了那個shuffle操作的reduce端的並行度。那么在進行shuffle操作的時候,就會對應着創建指定數量的reduce task)
方法的缺點:只是緩解了數據傾斜而已,沒有徹底根除問題,根據實踐經驗來看,其效果有限,該方案通常無法徹底解決數據傾斜,因為如果出現一些極端情況,比如某個key對應的數據量有100萬,那么無論你的task數量增加到多少,這個對應着100萬數據的key肯定還是會分配到一個task中去處理,因此注定還是會發生數據傾斜的。
(2)使用隨機key實現雙重聚合(groupByKey、reduceByKey比較適合使用這種方式)
實現原理:將原本相同的key通過附加隨機前綴的方式,變成多個不同的key,就可以讓原本被一個task處理的數據分散到多個task上去做局部聚合,進而解決單個task處理數據量過多的問題。接着去除掉隨機前綴,再次進行全局聚合,就可以得到最終的結果。
如下圖所示:
代碼:
object DataLean {
def main(args: Array[String]): Unit = {
//創建Spark配置對象
val conf = new SparkConf();
conf.setAppName("WordCountScala")
conf.setMaster("local") ;
//通過conf創建sc
val sc = new SparkContext(conf);
val rdd1=sc.textFile("F:/spark/b.txt",3);
rdd1.flatMap(_.split(" ")).map((_,1)).map(t=>{
val word=t._1
val r=Random.nextInt(100)
(word+"_"+r,1)
}).reduceByKey(_+_).map(t=>{
val word=t._1
val count=t._2
val w=word.split("_")(0)
(w,count)
}).reduceByKey(_+_).saveAsTextFile("F:/spark/lean/out")
}
}
(3):過濾少數導致傾斜的key
如果我們判斷那少數幾個數據量特別多的key,對作業的執行和計算結果不是特別重要的話,那么干脆就直接過濾掉那少數幾個key。比如,在Spark SQL中可以使用where子句過濾掉這些key或者在Spark Core中對RDD執行filter算子過濾掉這些key。如果需要每次作業執行時,動態判定哪些key的數據量最多然后再進行過濾,那么可以使用sample算子對RDD進行采樣,然后計算出每個key的數量,取數據量最多的key過濾掉即可。
參考文章:
1.https://blog.csdn.net/qq_38247150/article/details/80366769
2.https://blog.csdn.net/qq_38534715/article/details/78707759