Hadoop Yarn 資源調度器

資源調度器是 Hadoop Yarn 中最核心的組件之一。是 ResourceManager 中的一個插拔式服務組件,負責整個集群資源的管理和分配。

Yarn 提供了三種可用資源調度器:FIFO(先到先得),Capacity Scheduler(計算能力調度器),Fair Scheduler(公平調度器)。

資源調度器的發展

Hadoop 最初的設計是支持大數據批量作業,提供了非常簡單的 FIFO 調度機制,所有作業提交到一個隊列種,按照提交順序運行。

隨著 Hadoop 的發展,集群越來越大,使用用戶越來越多,不同用戶提交的任務往往具有不同的服務質量要求(Qos,Quality of Service),典型的有:

  • 批處理作業,往往耗時很長,對完成時間沒有嚴格要求
  • 交互式作業,期望能夠及時返回結果,如:Hive 查詢
  • 生產性作業,要求一定的資源保證,能夠在一段期望時間內完成

因此其他更加靈活,更充分利用資源的調度器誕生。為了適用多用戶的資源調度,目前主要有兩種多用戶資源調度器設計思路:第一種在物理集群上虛擬多個 Hadoop 集群,各自擁有全套獨立的 Hadoop 服務,典型代表是HOD(Hadoop on Demand)調度器;另一種是擴展 Yarn 調度器,支持多個隊列多個用戶。主要介紹 Yarn 調度器。

Yarn 資源調度器基本架構

基本架構

Yarn 的資源調度器是插拔式的,定義了一整套接口規范(用戶可以按需實現自己的調度器)。

yarn.resourcemanager.scheduler.class 參數設置使用哪種調度器,所有資源調度器都實現接口 org.apache.haddoop.yarn.server.resourcemanager.scheduler.ResourceScheduler

Yarn 資源管理器實際上是一個事件處理器,需要處理來自外部的6中 SchedulerEventType 類型的事件,并進行相應的處理

  • NODE_REMOVED,集群移除了一個計算節點(故障或手動移除),需要從可分配資源中移除
  • NODE_ADDED,集群新增了一個計算節點,需要將新增資源加入可分配資源中
  • APPLICATION_ADDED,ResourceManager 接收到一個新的 Application
  • APPLICATION_REMOVED,一個 Application 運行結束
  • CONTAINER_EXPIRED,ResourceManager 分配了 Container 給 ApplicationMaster,一定時間內 ApplicationMaster 沒有使用該 Container,會對資源進行回收再分配
  • NODE_UPDATE,ResourceManager 接收到 NodeManager 心跳消息后,觸發該事件

這些事件的觸發實現會影響資源調度器的資源分配機制

資源表示模型

當前 Yarn 支持內存和CPU兩種資源類型的管理和分配,采用動態資源分配機制。NodeManager 啟動時向 ResourceManager 注冊,包含該節點可分配的CPU和內存總量,可以通過配置項設置:

<!-- 可分配物理內存,默認:8GB -->
<property>
    <name>yarn.nodemanager.resource.memory-mb</name>
    <value>8192</value>
</property>

<!-- 單位物理內存最多可使用的虛擬內存量,默認:2.1 -->
<!-- 表示每使用1MB,最多可使用2.1MB虛擬內存 -->
<property>
    <name>yarn.nodemanager.vmem-pmem-ratio</name>
    <value>2.1</value>
</property>

<!-- 可分配的虛擬CPU個數,默認:8-->
<property>
    <name>yarn.nodemanager.resource.cpu-vcores</name>
    <value>4</value>
</property>

為了更細粒度的劃分CPU資源和考慮到CPU的性能異構性,Yarn 允許管理員根據實際需要和CPU性能將每個物理CPU劃分成若干個虛擬CPU,可以為每個節點單獨配置可用的虛擬CPU個數。

資源調度模型

雙層資源調度模型

Yarn 采用有雙層調度策略,ResourceManager 將資源分配給 ApplicationMaster,ApplicationMaster 再將資源分配給各個任務。

Yarn 的資源分配過程是異步的,將資源分配給一個應用程序后,不會立刻推給對應的 ApplicationMaster,會先放入一個緩沖區等待 ApplicationMaster 通過心跳來主動拉取,即 pull-based 通信模型(與MRv1一樣)。

  1. NodeManager 通過心跳向 ResourceManager 匯報節點信息
  2. ResourceManager 應答 NodeManager 的心跳請求,包括需要釋放的 Container 列表等信息
  3. ResourceManager 收到 NodeManager 的請求,觸發一個 NODE_UPDATE 事件
  4. ResourceScheduler 收到 NODE_UPDATE 事件,按照一定的策略分配該節點上的資源給各個應用程序,分配結果放到內存中
  5. ApplicationMaster 通過心跳向 ResourceManager 獲取最新分配的 Container
  6. ResourceManager 應答 ApplicationMaster 的心跳請求,發送分配資源結果
  7. ApplicationMaster 接收到分配的 Container 列表,將其分配給內部的任務

資源保證機制

當應用程序申請的資源暫時無法保證時,一種方法是為任務預留資源,直到積累充足的資源,稱為增量資源分配。另一種方式是:當資源不足以運行任務,放棄當前資源,直到出現能夠一次性滿足任務需求的資源出現,再分配給任務,稱為一次性資源分配。

Yarn 采用增量分配機制,雖然占用資源,造成資源浪費,但是第二種方式會產生餓死現象(應用程序永遠等不到滿足的資源)。

資源搶占模型

資源調度器中,每個隊列可以設置一個最小和最大資源量(資源緊缺時隊列能夠保證的資源量和極端情況下隊列不能超過的資源使用量)。資源搶占發生的原因在于最小資源量的設置,最小資源量并不能保證隊列空閑時依然占用資源。

通常為了提高資源利用率,調度器會將負載較輕的隊列資源暫時分配給負載重的隊列,當負載較輕隊列收到新提交的應用程序時,才會將本該數據該隊列的資源分配給他,但是由于此時這些資源可能正被其他隊列使用,因此只能等待其他隊列釋放這些資源。為了防止不確定的等待時間過長,調度器會進行資源搶占。

假設集群資源總量為100,分為三個隊列(分配最小和最大資源):QueueA(10, 15),QueueB(20, 35),QueueC(60, 65)

某一時刻他們需要的資源和使用的資源分別為:(0, 5)、(10, 30)、(60, 65),QueueA 負載較輕,部分資源暫時不會使用,將5個資源分給 QueueB(2) 和 QueueC(3),同時 QueueB 和 QueueC 除了使用 QueueA 的資源,還使用了系統共享的10個資源。

此時,QueueA 增加了新的應用程序,共需要20個資源,則調度器需要從 QueueB he QueueC 中搶占5個屬于 QueueA 的資源(通常會等待一段時間才強制回收資源)。整個過程如下圖:

搶占功能需要調度器實現 PreemptableResourceScheduler 接口,并且 yarn.resourcemanager.scheduler.monitor.enable 設置為 true 時才會啟用。

Yarn 層級隊列管理

層級隊列管理機制

在早期版本中,Hadoop 采用評級隊列組織方式,用戶和資源扁平化分配。隨著 Hadoop 的應用廣泛,扁平化的隊列組織已經不能滿足需求。出現了更復雜一些的層級隊列,具有以下特點:

  • 子隊列
    • 隊列可以嵌套
    • 應用程序只能提交到最底層的隊列
  • 最少容量
    • 每個子隊列都有“最少容量比”屬性,表示可使用父隊列容量的百分比
    • 調度器總是優先選擇當前資源使用率最低的隊列,并分配資源
  • 最大容量
    • 默認情況最大容量無限大,其他隊列空閑時,可以占用父隊列的全部資源

同時對于隊列的管理機制也隨著隊列的層級更加靈活。

層級隊列的命名:父隊列與子隊列采用“.”連接:

// 隊列命名
ROOT
ROOT.A
ROOT.A.A1
ROOT.A.A2
...

Capacity Scheduler

Yahoo! 開發的多用戶調度器,以隊列為單位劃分資源,主要有以下特點:

  • 計算能力保證。每個隊列會配置一定計算資源(最低資源保證和資源使用上限),所有提交到隊列中的作業共享該隊列中的資源。
  • 靈活性。隊列中空閑資源會被分配給那些未達到資源使用上限的隊列,在隊列有新的資源需求時,分配給其他隊列的資源會被歸還。
  • 多重租賃。綜合考慮多種約束防止單個作業、用戶或者隊列獨占隊列或者集群中的資源。
  • 安全保證。每個隊列有嚴格的ACL列表訪問控制。
  • 動態更新配置文件。各種配置參數可以由管理員動態修改,實現在線集群管理。

當前僅支持內存資源的調度

資源分配相關參數

配置項(百分比) 描述 解釋
capacity 隊列的資源容量 保證每個隊列的容量。
所有隊列容量之和應小于100。
maximum-capacity 隊列的資源上限 實際使用資源可以超過上限
minimun-user-limit-percent 每個用戶最低資源
user-limit-factor 每個用戶最低可使用資源量 任何時刻都不能超過

限制應用程序相關參數

配置項 描述 解釋
maximum-applications 處于等待和運行狀態的程序數量上限 強限制項
可以對集群和隊列設置
maximum-am-resource-percent 用于運行AppMaster的資源上限 百分比設置
可以對集群和隊列設置

訪問和權限控制相關參數

配置項 描述 解釋
state 隊列狀態 STOPPED/ RUNNING STOPPED隊列不可以提交應用程序
正在運行的可以正常結束
acl_submit_applications 限定可以提交應用程序的用戶 隊列具有繼承屬性
acl_administer_queue 指定隊列管理員

當需要動態修改隊列資源配置時,可修改配置文件 conf/capacity-scheduler.xml,然后運行 yarn mradmin -refreshQueues 命令。

Fair Shceduler

Facebook 開發的多用戶調度器,以隊列為單位劃分資源,主要有以下特點:

  • 資源公平共享。每個隊列中,可以按照FIFO、Fair(最大最小公平算法)或DRF(公平調度)策略分配資源。默認為Fair,如果隊列中有3個應用程序,各自能得到1/3的資源。
  • 支持資源搶占。隊列的剩余資源可以共享給其他隊列,并且可以在需要的時候回收資源。采用先等待再強制回收的策略,會殺死一部分任務來釋放資源。
  • 負載均衡。提供了一個基于任務數目的負載均衡機制,盡可能將任務均勻的分配到各個節點。
  • 提高小應用程序響應時間。采用的最大最小公平算法,允許小作業快速獲取資源。

Fair Shceduler 也添加了多層級別的資源限制條件。一部分配置在 yarn-site.xml 中,主要配置調度器級別的參數;另一部分在自定義配置文件(默認是 fair-scheduler.xml),主要配置各個隊列的資源和權重。

調度器配置項

配置項 描述
yarn.scheduler.fair.allocation.file 自定義配置文件的位置
yarn.scheduler.fair.user-as-default-queue 未指定隊列名時,是否指定用戶名作為提交程序的隊列名
yarn.scheduler.fair.preemption 啟用搶占機制,默認:false
yarn.scheduler.fair.assignmultiple 啟動批量分配大量資源,默認:false
yarn.scheduler.fair.max.assign 批量分配 Container 數目,默認:-1

隊列配置項

配置項 描述 解釋
minResource 最少資源保證 “X mb,Y vcores”
maxResource 最大資源限制 “X mb,Y vcores”
maxRunningApps 最多同時運行的數目
minSharePreemptionTimeout 最小共享量搶占時間 等待該時間后,強制釋放資源
schedulingMode
schedulingPolicy
隊列調度模式 FIFO\Fair\DRF
aclSubmitApps 限定可以提交應用程序的用戶 隊列具有繼承屬性
aclAdministerApps 指定隊列管理員

推薦書籍
《Hadoop技術內幕:深入解析YARN架構設計與實現原理》

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容