推廣一下本身的我的主頁zicesun.com函數
Spark的集羣調度其實蠻簡單的,這裏總結了一些集羣資源調度的基本原理。spa
spark集羣是怎麼管理集羣的計算資源和內存資源的呢?其實在這背後有一個資源註冊的機制。簡單來講,就是Worker節點講本身的資源報告給master。線程
首先,在Worker節點啓動的時候,Worker進程對應的worker類會實現一個WorkerArguments類從配置文件中讀取Worker進程相關的配置信息,或者使用默認值,包括分配給Worker的核心數和內存容量。若是沒有在配置文件配置這些資源,那麼則採起默認的值,可有inferDefaultCores方法和inferDefaultMemory方法獲得。若是配置文件中配置了,那麼則採用SPARK_WORKER_CORES和SPARK_WORKER_MEMORY設置的值。若是再啓動Worker的時候,顯式地指定了參數--core(--c)或者--memory(--m),則採用顯式制定的值。cdn
而後,Worker須要向Master進程註冊,彙報Worker擁有的計算資源和內存容量。在實現的時候,調用Worker類中的tryRegisterAllMaster方法,經過Akka通訊機制向Master節點發送註冊消息RegisterWorker。包括Worker的節點編號,主機地址,端口,用戶分配的內存以及核心數等信息。對象
最後,Master節點將Worker發送來的信息進行記錄,存儲在WorkerInfo對象中。blog
以上就是Worker資源註冊的過程。隊列
在集羣環境下,Driver程序經過實例化CoarseGrainedSchedulerBackend類實現Driver程序與集羣之間的通訊。不一樣的集羣模式實例化不一樣的CoarseGrainedSchedulerBackend子類。對於Standalone來講,使用的是SparkDeploySchedulerBackend類,該類在啓動的時候會實例化一個APPClient類,APPClient會想Master節點發送應用註冊請求,註冊請求含有應用須要的資源狀況。進程
Master節點在接收到應用程序的註冊請求以後,會把應用放在等待隊列中,並調用Master.scheduler方法,這個方法對應的是Master進程的驅動程序/應用程序調度邏輯:首先對Driver進程調度,在YARN集羣模式下,Driver程序能夠運行在worker節點上,所以Master節點須要專門分配相應的集羣資源來運行Driver進程,採用的方法就是隨機把Driver分配到空閒的Worker上。內存
具體的應用程序的調度,多個應用程序之間採用FIFO調度方法,按照應用程序註冊的前後順序分配資源。對於單個應用程序之間,則有SpreadOut和非SpreadOut兩種調度策略。在分配資源以前,Master須要查詢當前集羣的內存資源是否知足運行應用程序最低的需求,而且以前爲這個應用程序分配過Executor的Worker不能參與資源調度,一個應用程序在一個Worker上只能有一個Executor。資源
SpreadOut策略,Master採用輪詢的方式,讓每一個可用的Worker爲應用程序分配一個核心,知道分配的核心知足應用程序的需求。 非SpreadOut策略,會一次性把一個Worker上全部可分配的核心所有分配給應用程序。
被分配任務的Worker會調用addExecutor函數來添加相應的Executor,並調用launchExecutor方法啓動Executor,改方法會記錄Worker被消耗的資源,並向對應的Worker發送消息,通知其啓動Executor。Worker接收到消息以後,會記錄資源消耗量,並啓動新的Executor進程。
上圖是YARN集羣模式下資源調度的流程圖,根據這幅圖,咱們也能夠了解資源調度的狀況。 提交一個Spark應用程序,首先經過Client向ResourceManager請求啓動一個Application,同時檢查是否有足夠的資源知足Application的需求,若是資源條件知足,則準備ApplicationMaster的啓動上下文,交給ResourceManager,並循環監控Application狀態。當提交的資源隊列中有資源時,ResourceManager會在某個NodeManager上啓動ApplicationMaster進程,ApplicationMaster會單獨啓動Driver後臺線程,當Driver啓動後,ApplicationMaster會經過本地的RPC鏈接Driver,並開始向ResourceManager申請Container資源運行Executor進程(一個Executor對應與一個Container),當ResourceManager返回Container資源,則在對應的Container上啓動Executor。
Driver線程主要是初始化SparkContext對象,準備運行所需的上下文,而後一方面保持與ApplicationMaster的RPC鏈接,經過ApplicationMaster申請資源,另外一方面根據用戶業務邏輯開始調度任務,將任務下發到已有的空閒Executor上。
當ResourceManager向ApplicationMaster返回Container資源時,ApplicationMaster就嘗試在對應的Container上啓動Executor進程,Executor進程起來後,會向Driver註冊,註冊成功後保持與Driver的心跳,同時等待Driver分發任務,當分發的任務執行完畢後,將任務狀態上報給Driver。