1. SparkShuffle
1. SparkShuffle概念
reduceByKey會將上一個RDD中的每一個key對應的所有value聚合成一個value,然後生成一個新的RDD,元素類型是<key,value>對的形式,這樣每一個key對應一個聚合起來的value。
問題:聚合之前,每一個key對應的value不一定都是在一個partition中,也不太可能在同一個節點上,因爲RDD是分佈式的彈性的數據集,RDD的partition極有可能分佈在各個節點上。
如何聚合?
–Shuffle Write:上一個stage的每個map task就必須保證將自己處理的當前分區的數據相同的key寫入一個分區文件中,可能會寫入多個不同的分區文件中。
– Shuffle Read:reduce task就會從上一個stage的所有task所在的機器上尋找屬於己的那些分區文件,這樣就可以保證每一個key所對應的value都會匯聚到同一個節點上去處理和聚合。
Spark中有兩種Shuffle類型,HashShuffle和SortShuffle,Spark1.2之前是HashShuffle默認的分區器是HashPartitioner,Spark1.2引入SortShuffle默認的分區器是RangePartitioner。
2. HashShuffle
1) 普通機制
Ø 普通機制示意圖
Ø 執行流程
a) 每一個map task將不同結果寫到不同的buffer中,每個buffer的大小爲32K。buffer起到數據緩存的作用。
b) 每個buffer文件最後對應一個磁盤小文件。
c) reduce task來拉取對應的磁盤小文件。
Ø 總結
① .map task的計算結果會根據分區器(默認是hashPartitioner)來決定寫入到哪一個磁盤小文件中去。ReduceTask會去Map端拉取相應的磁盤小文件。
② .產生的磁盤小文件的個數:
M(map task的個數)* R(reducetask的個數)
Ø 存在的問題
產生的磁盤小文件過多,會導致以下問題:
a) 在Shuffle Write過程中會產生很多寫磁盤小文件的對象。
b) 在Shuffle Read過程中會產生很多讀取磁盤小文件的對象。
c) 在JVM堆內存中對象過多會造成頻繁的gc,gc還無法解決運行所需要的內存 的話,就會OOM。
d) 在數據傳輸過程中會有頻繁的網絡通信,頻繁的網絡通信出現通信故障的可能性大大增加,一旦網絡通信出現了故障會導致shuffle file cannot find 由於這個錯誤導致的task失敗,TaskScheduler不負責重試,由DAGScheduler負責重試Stage。
2) 合併機制
Ø 合併機制示意圖
Ø 總結
產生磁盤小文件的個數:C(core的個數)*R(reduce的個數)
3. SortShuffle
1) 普通機制
Ø 普通機制示意圖
Ø 執行流程
a) map task 的計算結果會寫入到一個內存數據結構裏面,內存數據結構默認是5M
b) 在shuffle的時候會有一個定時器,不定期的去估算這個內存結構的大小,當內存結構中的數據超過5M時,比如現在內存結構中的數據爲5.01M,那麼他會申請5.01*2-5=5.02M內存給內存數據結構。
c) 如果申請成功不會進行溢寫,如果申請不成功,這時候會發生溢寫磁盤。
d) 在溢寫之前內存結構中的數據會進行排序分區
e) 然後開始溢寫磁盤,寫磁盤是以batch的形式去寫,一個batch是1萬條數據,
f) map task執行完成後,會將這些磁盤小文件合併成一個大的磁盤文件,同時生成一個索引文件。
g) reduce task去map端拉取數據的時候,首先解析索引文件,根據索引文件再去拉取對應的數據。
Ø 總結
產生磁盤小文件的個數: 2*M(map task的個數)
2) bypass機制
Ø bypass機制示意圖
Ø 總結
① .bypass運行機制的觸發條件如下:
shuffle reduce task的數量小於spark.shuffle.sort.bypassMergeThreshold的參數值。這個值默認是200。
② .產生的磁盤小文件爲:2*M(map task的個數)
4. Shuffle文件尋址
1) MapOutputTracker
MapOutputTracker是Spark架構中的一個模塊,是一個主從架構。管理磁盤小文件的地址。
Ø MapOutputTrackerMaster是主對象,存在於Driver中。
Ø MapOutputTrackerWorker是從對象,存在於Excutor中。
2) BlockManager
BlockManager塊管理者,是Spark架構中的一個模塊,也是一個主從架構。
Ø BlockManagerMaster,主對象,存在於Driver中。
BlockManagerMaster會在集羣中有用到廣播變量和緩存數據或者刪除緩存數據的時候,通知BlockManagerSlave傳輸或者刪除數據。
Ø BlockManagerWorker,從對象,存在於Excutor中。
BlockManagerWorker會與BlockManagerWorker之間通信。
¬ 無論在Driver端的BlockManager還是在Excutor端的BlockManager都含有四個對象:
① DiskStore:負責磁盤的管理。
② MemoryStore:負責內存的管理。
③ ConnectionManager:負責連接其他的BlockManagerWorker。
④ BlockTransferService:負責數據的傳輸。
3) Shuffle文件尋址圖
4) Shuffle文件尋址流程
a) 當map task執行完成後,會將task的執行情況和磁盤小文件的地址封裝到MpStatus對象中,通過MapOutputTrackerWorker對象向Driver中的MapOutputTrackerMaster彙報。
b) 在所有的map task執行完畢後,Driver中就掌握了所有的磁盤小文件的地址。
c) 在reduce task執行之前,會通過Excutor中MapOutPutTrackerWorker向Driver端的MapOutputTrackerMaster獲取磁盤小文件的地址。
d) 獲取到磁盤小文件的地址後,會通過BlockManager中的ConnectionManager連接數據所在節點上的ConnectionManager,然後通過BlockTransferService進行數據的傳輸。
e) BlockTransferService默認啓動5個task去節點拉取數據。默認情況下,5個task拉取數據量不能超過48M。