Spark on Mesos: 粗粒度與細粒度實現分析

背景

順着昨天spark standalone實現那篇文章繼續扯淡,看看Mesos Scheduler的兩種實現的異同。

對我來說,回過頭再仔細看Spark在這一層的實現,思路又清晰了許多。


Mesos粗粒度

CoarseMesosSchedulerBackend,是mesos的粗粒度scheduler backend實現。


簡單說一下mesos的Scheduler,提供的回調函數,及spark實現的邏輯:


Mesos Scheduler回調接口一覽
Mesos Scheduler接口觸發場景spark實現邏輯
void registered(
  SchedulerDriver driver,
   FrameworkID frameworkId,
   MasterInfo masterInfo);
當Scheduler成向mesos master註冊之後回調,
會返回唯一的framework id
得到framework的id,作爲appId
void reregistered(
  SchedulerDriver driver,
   MasterInfo masterInfo)
是mesos換了個新選舉出來的master的時候觸發,
前提是該scheduler之前已經註冊過了
沒有實現。
void resourceOffers(
  SchedulerDriver driver,
  List<Offer> offers)
mesos提供了一批可用的資源,讓scheduler可以使用或拒絕這些資源。
每個Offer是以slave爲單位的,即以slave爲單位的資源列表。
得到mesos的Offers列表,只要已經啓動的executor還不足夠,
那麼從資源列表裏繼續獲取資源,啓動CoarseGrainedExecutorBackend。
void offerRescinded(
  SchedulerDriver driver,  
  OfferID offerId)
當請求的offer不可用時回調(可能是slave lost了之類的原因導致的),
如果在這上面繼續起task的話會報Task Lost的狀態。
沒有實現。spark在task scheduler層面對lost的task有自己的處理,。
void statusUpdate(
  SchedulerDriver driver,
  TaskStatus status)
task狀態更新回調,可能是finish了,可能是lost了,可能是fail了等等得到finished、failed、lost等task狀態,更新內存裏維護的task狀態,
並觸發新一輪的reviveOffers,即通過task scheduler繼續把resource分配給需要的task並執行它們。
void frameworkMessage(
  SchedulerDriver driver,
  ExecutorID executorId,
  SlaveID slaveId,
  byte[] data)
用於接收executor主動發的消息沒有實現。mesos雖然在內部提供了這種msg接口,貌似不是很穩定。
使用方可以使用自己的RPC來做executor與scheduler的通信,如果真的需要的話。
void disconnected(
  SchedulerDriver driver)
當scheduler與master斷開的時候觸發,
原因可能是master掛了,或者master換了等等。
沒有實現。spark前面就沒有實現master新選舉的接口。
void slaveLost(
  SchedulerDriver driver,
   SlaveID slaveId)
通知某個slave lost了,以便framework進行任務的rescheduler或其他邏輯spark把slave lost和executor lost一起處理了。
處理邏輯就是執行RemoveExecutor操作,最終調用TaskScheduler的executorLost方法,把executor的狀態移除,
並且會繼續向上調用DAGScheduler的handleExecutorLost方法。
因executor lost可能會影響到shuffle數據,這部分還需要BlockManager感知。
void executorLost(
  SchedulerDriver driver,
  ExecutorID executorId,
  SlaveID slaveId,
  int status)
通知某個slave上的executor掛了。同上
void error(
 SchedulerDriver driver,
  String message)
scheduler或scheduler driver發送錯誤觸發沒有實現


另一方面,要說明一下mesos的SchedulerDriver。

它相當於是Scheduler與mesos通信的一個連接人,一方面是管理Scheduler的生命週期,二方面是與mesos交互,讓它啓停task。

在初始化SchedulerDriver的時候,向裏面傳入spark自己實現的Scheduler就可以了,即CoarseMesosSchedulerBackend或MesosSchedulerBackend。在每個mesos的Scheduler接口的回調方法裏,都會傳回SchedulerDriver,以對應可以進行scheduler的啓停和task的啓停管理。


CoarseMesosSchedulerBackend內部主要維護的信息爲:slave與executor的對應關係,executor與task的對應關係,task與slave的對應關係。


Mesos細粒度

翻譯下注釋:

細粒度模式下,允許多個app共享nodes,包括空間,即不同app的tasks可以跑同幾個core,和時間,即一個core可以切換ownership。

這塊共享的控制,在mesos端,所以spark在實現的時候,其實差別和難度都不大。

 

MesosSchedulerBackend的實現:

在resourceOffers邏輯裏,獲得mesos提供的slave資源後,直接在裏面調用scheduler的resourceOffers,即TaskSchedulerImpl的分配task的邏輯。也就是說,會按優先級,從active task sets(來自多個app)裏選擇並直接launch task。而粗粒度裏的做法,是先啓動executorbackend,把資源準備好,進程先拉起,供app去launch task。

 

其他回調接口的邏輯是大同小異的。

 

還有一點不同之處,粗粒度模式下executor的實現使用的是與standalone模式相同的CoarseGrainedExecutorBackend。在細粒度模式下,executor的實現是MesosExecutorBackend,實現了spark的ExecutorBackend和mesos的MesosExecutor。實際上,在類裏面,還是使用的spark的executor,在對應的回調裏執行start/kill task這樣的操作。另外,mesos的ExecutorDriver用於負責與mesos通信,比如傳遞一些狀態更新的消息,或有特殊的msg要發送。executor這塊的差別無關緊要。

 

在我看來,executor這塊最終一定是落到了spark的executor上,裏面有一個線程池,可以跑spark的ShuffleMapTask或ResultTask。而mesos粗、細粒度的Scheduler實現,最大區別在於resourceOffers的邏輯,是怎麼處理分配的進程資源:粗粒度是預先拉起執行進程,而細粒度是直接通過TaskScheduler來擺放執行線程了。


粗細粒度分別適合跑什麼樣的任務,可以具體見 官方文檔這一節


全文完  :)



發佈了158 篇原創文章 · 獲贊 25 · 訪問量 94萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章