梳理對Spark Standalone的理解

jopen 9年前發布 | 14K 次閱讀 Spark 分布式/云計算/大數據

原文  http://blog.csdn.net/pelick/article/details/43762375

背景

本文不打算從源碼分析的角度看standalone如何實現,甚至有的模塊和類在分析中都是忽略掉的。

本文目的是透過spark的standalone模式,看類似spark這種執行模式的系統,在設計和考慮與下次資源管理系統對接的時候,有什么 值得參考和同通用的地方,比如說接口和類體系,比如說各個執行層次的劃分:面向資源的部分 vs 面向擺放的部分;面向資源里面進程的部分 vs 線程的部分等。對這些部分談談體會。

執行流程

梳理對Spark Standalone的理解

解釋standalone執行原理可以拋開Driver和Client。

首先,簡單說明下Master、Worker、App三種角色。

Application:帶有自己需要的mem和cpu資源量,會在master里排隊,最后被分發到worker上執行。app的啟動是去各個worker遍歷,獲取可用的cpu,然后去各個worker launch executor。

Worker:每臺slave起一個,默認或被設置cpu和mem數,并在內存里做加減維護資源剩余量。Worker同時負責拉起本地的executor backend,即執行進程。

Master:接受Worker、app的注冊,為app執行資源分配。Master和Worker本質上都是一個帶Actor的進程。

接下來分析下圖中的四個步驟。

第一步,register worker是一個啟動集群和搜集初始資源的過程。在standalone模式下,預先在機器上使用腳本start master和slave。在這個過程中,worker的啟動cpu和內存是設置好的,起來后把自己注冊給master,從而master維護 worker上的資源量和worker本身host、port等的信息。master的HA拋開不談。

第二步,master接收新app的注冊。app也好,driver也好,都是通過輸入一個spark url提交的,最終在master內存里排隊。當master有新的app進來,或資源可用性發生變化時,會觸發資源分配的邏輯:

首先,將可用的alive workers進行洗牌打亂,遍歷等待的drivers,為每個driver輪詢遍歷alive workers,只要worker的剩余mem和cpu滿足該driver,那么就向那個worker通過actor sender發送一個LaunchDriver的消息,里面會包含driver的信息。

接著,遍歷所有的waiting apps,同樣為每個app遍歷可用的worker,為其分配cpu。默認是spread out的策略,即一個app的cpus可以分布在不同的worker上。app會添加自己的executor,然后向Worker的actor傳遞 LaunchExecutor的消息,并傳遞給這個app的driver一個ExecutorAdded的消息。

第三步,launch executor是一個重點。master在資源分配的邏輯里,為app分配了落在若干worker上的executors,然后對于每一個 executor,master都會通知其worker去啟動。standalone模式下,每個worker通過command命令行的方式啟動 CoarseGrainedExecutorBackend。CoarseGrainedExecutorBackend本質上也是一個Actor,里面 最重要的是有一個線程池,可以執行真正的task。所以CoarseGrainedExecutorBackend具備了 launchTask,killTask等方法,其TaskRunner的run()方法,調用的就是ShuffleMapTask或 ResultTask的run()邏輯。

第四步,app自己來launch task。上面三步都是集群資源的準備過程,在這個過程里,app得到了屬于自己的資源,包括cpu、內存、起起來的進程及其分布。在我看來,前三個過程是 面向資源 的調度過程,接在mesos、yarn上也可以,而第四個過程則是 面向擺放 的。App內的TaskScheduler和SchedulerBackend是我們熟悉的與task切分、task分配、task管理相關的內容。在之前spark任務調度的文章里也啰啰嗦嗦講了一些。

模型分層

spark在這一塊的設計是優秀的。圖中,app內的SchedulerBackend是可以針對不同資源管理系統實現的,包括沒有畫出來的 ExecutorBackend。這倆兄弟是典型的面向資源的層次上的抽象。另一方面,app內的TaskScheduler是與Task的分配和執行、 管理相關的,這部分與下層面向資源的部分是隔離開的,所謂是面向擺放的。

換句話說,SchedulerBackend在1,2,3步之后,已經從集群里,獲得了本身app的executors資源。通過 它,TaskScheduler可以根據自己的策略,把Task與Executor對應起來,啟動起來,管理起來。原本,TaskScheduler是個 邏輯上的任務調度者,加上SchedulerBackend之后,其具備了操縱實際物理資源的能力,當然主要指的就是task locality與task在進程上的start和kill。

我對standalone的感受是,spark的資源索取和執行,其實是偏向于一個在線系統的。spark要跑一個app之前,也是先申請好資源 量的,且資源都保證的情況下,app會一下被分配到所有資源,并得到了使用這些資源的能力。無論是mesos上還是yarn上,實現上無非主要是 SchedulerBackend和Executor相關類的區別,上層邏輯上的任務調度,即TaskScheduler是不變的。

今天,我對于standalone的重看和理解,最受益的就是在線系統與資源管理銜接上的分層理解。其實資源管理系統很容易從雙層,三層,劃分到 邏輯上四、五層。至少,我看spark在這件事情上的設計還是很清晰,有借鑒意義的。甚至standalone這套東西,也是可以單獨拎出來支持其他系統 的。

全文完 :)

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!