Spark學習(5)——Spark源碼學習(1)

一、廣播變量和累加器

1.1、廣播變量

(1)廣播變量使用

val conf = new SparkConf()
conf.setMaster("local").setAppName("brocast")
val sc = new SparkContext(conf)
val list = List("hello xasxt")
val broadCast = sc.broadcast(list)
val lineRDD = sc.textFile("./words.txt")
lineRDD.filter { x => broadCast.value.contains(x) }.foreach { println}
sc.stop()

(2)注意事項

  • 能不能將一個RDD使用廣播變量廣播出去?

不能,因爲RDD是不存儲數據的。可以將RDD的結果廣播出去。

  • 廣播變量只能在Driver端定義,不能在Executor端定義。
  • 在Driver端可以修改廣播變量的值,在Executor端無法修改廣播變量的值。

1.2、累加器

(1)累加器的使用

val conf = new SparkConf()
conf.setMaster("local").setAppName("accumulator")
val sc = new SparkContext(conf)
val accumulator = sc.accumulator(0)
sc.textFile("./words.txt").foreach { x =>{accumulator.add(1)}}
println(accumulator.value)
sc.stop()

(2)注意事項

  • 累加器在Driver端定義賦初始值,累加器只能在Driver端讀取,在Excutor端更新。

二、Master HA

2.1、Master的高可用原理

Standalone集羣只有一個Master,如果Master掛了就無法提交應用程序,需要給Master進行高可用配置,Master的高可用可以使用fileSystem(文件系統)和zookeeper(分佈式協調服務)。

fileSystem只有存儲功能,可以存儲Master的元數據信息,用fileSystem搭建的Master高可用,在Master失敗時,需要我們手動啓動另外的備用Master,這種方式不推薦使用。

zookeeper有選舉和存儲功能,可以存儲Master的元素據信息,使用zookeeper搭建的Master高可用,當Master掛掉時,備用的Master會自動切換,推薦使用這種方式搭建Master的HA。

三、SparkShuffle

3.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都會匯聚到同一個節點上去處理和聚合。

3.2、HashShuffleManager

(1)普通機制

執行流程:

  1. 每一個map task將不同結果寫到不同的buffer中,每個buffer的大小爲32K。buffer起到數據緩存的作用。
  2. 每個buffer文件最後對應一個磁盤小文件。
  3. reduce task來拉取對應的磁盤小文件。

總結:

  • .map task的計算結果會根據分區器(默認是hashPartitioner)來決定寫入到哪一個磁盤小文件中去。ReduceTask會去Map端拉取相應的磁盤小文件。
  • .產生的磁盤小文件的個數:M(map task的個數)*R(reduce task的個數)

存在的問題:

產生的磁盤小文件過多,會導致以下問題:
(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.3、SortShuffleManager

(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運行機制的觸發條件如下:

shuffle reduce task的數量小於spark.shuffle.sort.bypassMergeThreshold的參數值。這個值默認是200。

  • .產生的磁盤小文件爲:2*M(map task的個數)

3.4、Shuffle文件尋址

流程:

a)	當map task執行完成後,會將task的執行情況和磁盤小文件的地址封裝到MpStatus對象中,通過MapOutputTrackerWorker對象向Driver中的MapOutputTrackerMaster彙報。
b)	在所有的map task執行完畢後,Driver中就掌握了所有的磁盤小文件的地址。
c)	在reduce task執行之前,會通過Excutor中MapOutPutTrackerWorker向Driver端的MapOutputTrackerMaster獲取磁盤小文件的地址。
d)	獲取到磁盤小文件的地址後,會通過BlockManager連接數據所在節點,然後通過BlockTransferService進行數據的傳輸。
e)	BlockTransferService默認啓動5個task去節點拉取數據。默認情況下,5個task拉取數據量不能超過48M。

 

(1)MapOutputTracker

MapOutputTracker是Spark架構中的一個模塊,是一個主從架構。管理磁盤小文件的地址。

  • MapOutputTrackerMaster是主對象,存在於Driver中
  • MapOutputTrackerWorker是從對象,存在於Excutor中

(2)BlockManager

BlockManager塊管理者,是Spark架構中的一個模塊,也是一個主從架構。

  • BlockManagerMaster,主對象,存在於Driver中

BlockManagerMaster會在集羣中有用到廣播變量和緩存數據或者刪除緩存數據的時候,通知BlockManagerSlave傳輸或者刪除數據。

  • BlockManagerSlave,從對象,存在於Excutor中

(3)BlockManagerSlave會與BlockManagerSlave之間通信。

  • 無論在Driver端的BlockManager還是在Excutor端的BlockManager都含有三個對象:
  • DiskStore:負責磁盤的管理。
  • MemoryStore:負責內存的管理。
  • BlockTransferService:負責數據的傳輸。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章