Spark Dynamic Allocation 源碼解析

爲什麼研究Dynamic Allocation的源碼?

在線上任務執行的過程中,有些任務佔用着Yarn資源卻並行度極低,比如申請了100核cpu(現象持續時間超過了executor idle time),但那個stage只有9個running task。
最關鍵的是,在Spark-SQL中,Dynamic Allocation可以說是必用功能之一。因此知曉其原理才能更好的理解Spark動態資源調度。

什麼是Dynamic Allocation,爲什麼要Dynamic Allocation?

無論用什麼資源管理,集羣的資源總是有限的並且競爭激烈的。因此,彈性的思想就很關鍵,用多少拿多少、用完還回去。
想到現在很多雲服務器的思想都和這個極爲相似,服務器按小時租,按量收費,一個用戶就相當於一個任務,雲服務就像Yarn管理資源分配,誰要資源就立即分配。

Dynamic Allocation早在Spark1.2就被開發出來使用了,到現在已經是非常的成熟和完善了。
相關參數可以參考我之前寫的spark 參數調優10-Dynamic Allocation

源碼解析

Dynamic Allocation核心代碼實現就在ExecutorAllocationManager中。
先保留兩個問題:

  1. 如何衡量當前任務需要消耗多少資源?
  2. 什麼時候該去向集羣申請資源?

先計算出每個executor最大並行度:
在這裏插入圖片描述
因此我們可以建立task和executor之間的聯繫。
所以我們可以得出結論:如果有100個task,每個executor最大並行度爲10,則我們最多需要10個executor。
代碼實現如下:
在這裏插入圖片描述
這邊要注意的是executorAllocationRatio,這個比例範圍在0~1.0之間,默認爲1.0,控制了任務和資源的比例,在資源非常珍貴的場景下,可以適當調小這個參數,比如之前的100個task,我們本來打算給他10個executor,如果將此參數設爲0.5,那麼這100個task只能申請到5個executor了。該參數如下:
在這裏插入圖片描述
updateAndSyncNumExecutorsTarget:更新當前executor的數量,返回爲需要增(正數)減(負數)的executor數量:
在這裏插入圖片描述
這我們不難發現,不管是需要增加(調用addExecutors)還是減少executor,都會使用到client.requestTotalExecutors,其調用了CoarseGrainedSchedulerBackend中的requestTotalExecutors:
在這裏插入圖片描述
在向cluster manager申請executor時,加了一把鎖,防止重複申請executor。

Spark向YARN申請資源

YarnSchedulerBackend中doRequestTotalExecutors:
在這裏插入圖片描述
prepareRequestExecutors:
在這裏插入圖片描述

什麼時候觸發executor移除?

同樣在ExecutorAllocationManager中我們可以看到:
在這裏插入圖片描述
默認100ms會執行一次schedule():
在這裏插入圖片描述
這邊獲取到了超時的executor,然後進行remove操作。

小結

Spark Dynamic Allocation的核心代碼大致上就這些,主要用於申請和釋放executor,在不同場景下,保證不會多申請,當然active的executor也不能低於設定的最低值。
至於CoarseGrainedSchedulerBackend是怎麼維護executor的,會在後續的文章給出答案。

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