Apache Spark源碼走讀之1 -- Spark論文閱讀筆記

歡迎轉載,轉載請註明出處,徽滬一郎。node

楔子

源碼閱讀是一件很是容易的事,也是一件很是難的事。容易的是代碼就在那裏,一打開就能夠看到。難的是要經過代碼明白做者當初爲何要這樣設計,設計之初要解決的主要問題是什麼。web

在對Spark的源碼進行具體的走讀以前,若是想要快速對Spark的有一個總體性的認識,閱讀Matei Zaharia作的Spark論文是一個很是不錯的選擇。編程

在閱讀該論文的基礎之上,再結合Spark做者在2012 Developer Meetup上作的演講Introduction to Spark Internals,那麼對於Spark的內部實現會有一個比較大概的瞭解。緩存

有了上述的兩篇文章奠基基礎以後,再來進行源碼閱讀,那麼就會知道分析的重點及難點。分佈式

基本概念(Basic Concepts)

RDD - resillient distributed dataset 彈性分佈式數據集ide

Operation - 做用於RDD的各類操做分爲transformation和actionspa

Job - 做業,一個JOB包含多個RDD及做用於相應RDD上的各類operation線程

Stage - 一個做業分爲多個階段scala

Partition - 數據分區, 一個RDD中的數據能夠分紅多個不一樣的區設計

DAG - Directed Acycle graph, 有向無環圖,反應RDD之間的依賴關係

Narrow dependency - 窄依賴,子RDD依賴於父RDD中固定的data partition

Wide Dependency - 寬依賴,子RDD對父RDD中的全部data partition都有依賴

Caching Managenment -- 緩存管理,對RDD的中間計算結果進行緩存管理以加快總體的處理速度

編程模型(Programming Model)

RDD是隻讀的數據分區集合,注意是數據集

做用於RDD上的Operation分爲transformantion和action。 經Transformation處理以後,數據集中的內容會發生更改,由數據集A轉換成爲數據集B;而經Action處理以後,數據集中的內容會被歸約爲一個具體的數值。

只有當RDD上有action時,該RDD及其父RDD上的全部operation纔會被提交到cluster中真正的被執行。

從代碼到動態運行,涉及到的組件以下圖所示。

 

演示代碼

val sc = new SparkContext("Spark://...", "MyJob", home, jars)
val file = sc.textFile("hdfs://...")
val errors = file.filter(_.contains("ERROR"))
errors.cache()
errors.count()

運行態(Runtime view)

無論什麼樣的靜態模型,其在動態運行的時候無外乎由進程,線程組成。

用Spark的術語來講,static view稱爲dataset view,而dynamic view稱爲parition view. 關係如圖所示

 

在Spark中的task能夠對應於線程,worker是一個個的進程,worker由driver來進行管理。

那麼問題來了,這一個個的task是如何從RDD演變過來的呢?下節將詳細回答這個問題。

部署(Deployment view)

當有Action做用於某RDD時,該action會做爲一個job被提交。

在提交的過程當中,DAGScheduler模塊介入運算,計算RDD之間的依賴關係。RDD之間的依賴關係就造成了DAG。

每個JOB被分爲多個stage,劃分stage的一個主要依據是當前計算因子的輸入是不是肯定的,若是是則將其分在同一個stage,避免多個stage之間的消息傳遞開銷。

當stage被提交以後,由taskscheduler來根據stage來計算所須要的task,並將task提交到對應的worker.

Spark支持如下幾種部署模式1)standalone 2)Mesos 3) yarn. 這些部署模式將做爲taskscheduler的初始化入參。

RDD接口(RDD Interface)

RDD由如下幾個主要部分組成

  1. partitions --    partition集合,一個RDD中有多少data partition
  2. dependencies -- RDD依賴關係
  3. compute(parition) -- 對於給定的數據集,須要做哪些計算
  4. preferredLocations --  對於data partition的位置偏好
  5. partitioner -- 對於計算出來的數據結果如何分發

緩存機制(caching)

RDD的中間計算結果能夠被緩存起來,緩存先選Memory,若是Memory不夠的話,將會被寫入到磁盤中。

根據LRU(last-recent update)來決定哪先內容繼續保存在內存,哪些保存到磁盤。

容錯性(Fault-tolerant)

從最初始的RDD到衍生出來的最後一個RDD,中間要通過一系列的處理。那麼如何處理中間環節出現錯誤的場景呢?

Spark提供的解決方案是隻對失效的data partition進行事件重演,而無須對整個數據全集進行事件重演,這樣能夠大大加快場景恢復的開銷。

RDD又是如何知道本身的data partition的number該是多少?若是是hdfs文件,那麼hdfs文件的block將會成爲一個重要的計算依據。

集羣管理(cluster management)

task運行在cluster之上,除了spark自身提供的standalone部署模式以外,spark還內在支持yarn和mesos.

Yarn來負責計算資源的調度和監控,根據監控結果來重啓失效的task或者是從新distributed task一旦有新的node加入cluster的話。

這一部分的內容須要參考yarn的文檔。

小結

在源碼閱讀時,須要重點把握如下兩大主線。

  • 靜態view 即 RDD, transformation and action
  • 動態viewlife of a job, 每個job又分爲多個stage,每個stage中能夠包含多個rdd及其transformation,這些stage又是如何映射成爲task被distributed到cluster中

參考資料(reference)

  1. Introduction to Spark Internals http://files.meetup.com/3138542/dev-meetup-dec-2012.pptx
  2. Resilient Distributed Datasets: A Fault-tolerant Abstraction for In-Memory Cluster Computing  https://www.usenix.org/system/files/.../nsdi12-final138.pdf
  3. Lightning-Fast Cluster Computing with Spark and Shark   http://www.meetup.com/TriHUG/events/112474102/
相關文章
相關標籤/搜索