YARN中的任務隊列調度器-容量調度器(Capacity Scheduler)

一、概述

    容量調度器是YARN提供的三種調度器中的一種,這種調度器允許多個組織(隊列)共享一個Hadoop集羣,每個組織(隊列)所分配的集羣資源是固定的且可配置的。每個組織(隊列)內部還可以進一步劃分成小隊列,小隊列之間共享整個組織(隊列)的資源。在一個隊列中,使用FIFO規則進行任務調度。

    容量調度器是Hadoop默認使用的調度器,但是像CDH這樣的Hadoop分佈式項目,默認使用的公平調度器(Fair Scheduler)。

二、配置

1. 修改YARN使用的調度器:

位置:$HADOOP_HOME/etc/hadoop/yarn-site.xml

添加配置:

    key: yarn.resourcemanager.scheduler.class

    value: org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler

2. 定義調度隊列

位置:$HADOOP_HOME/etc/hadoop/capacity-scheduler.xml

我本地設置了四個調度隊列,它們的結構模型如下:

root 

    --default

    --bigdataU

    --azkaban

首先,root隊列下分別是三個子隊列:default、bigdataU、azkaban,配置隊列選項我們可以直接在配置文件中使用

yarn.scheduler.capacity.<queue-path>.<sub-property>作爲key,例如,我需要爲root.default配置集羣資源佔比,那麼可以寫:

  <property>
        <name>yarn.scheduler.capacity.root.default.capacity</name>
        <value>20</value>
  </property>

配置規則講完了,那麼下面就是我們可以爲隊列配置的信息:

yarn.scheduler.capacity.<queue-path>.capacity:隊列在整個組織(隊列)的資源佔比;

yarn.scheduler.capacity.<queue-path>.maximum-capacity:隊列在整個組織(隊列)所佔資源最大佔比,這涉及到調度彈性;

yarn.scheduler.capacity.<queue-path>.state:有兩個候選值,RUNNING是正常運行,STOPPED是停止工作,隊列如果是STOPPED狀態,那麼系統將不能提交任務到這個隊列以及這個隊列的子隊列。

其他還有很多配置,如同時運行應用的數量、隊列的ACL認證等,詳情可以看一下這位仁兄的博客:Capacity Scheduler相關參數 

接下來,我把我的配置文件部分信息也發上來:

<property>
        <name>yarn.scheduler.capacity.root.default.capacity</name>
        <value>20</value>
  </property>
  <property>
        <name>yarn.scheduler.capacity.root.default.maximum-capacity</name>
        <value>45</value>
  </property>
  <property>
        <name>yarn.scheduler.capacity.root.default.state</name>
        <value>RUNNING</value>
  </property>
  <property>
        <name>yarn.scheduler.capacity.root.bigdataU.capacity</name>
        <value>40</value>
  </property>
  <property>
        <name>yarn.scheduler.capacity.root.bigdataU.maximum-capacity</name>
        <value>55</value>
  </property>
  <property>
        <name>yarn.scheduler.capacity.root.bigdataU.state</name>
        <value>RUNNING</value>
  </property>
  <property>
        <name>yarn.scheduler.capacity.root.azkaban.capacity</name>
        <value>40</value>
  </property>
  <property>
        <name>yarn.scheduler.capacity.root.azkaban.maximum-capacity</name>
        <value>45</value>
  </property>
  <property>
        <name>yarn.scheduler.capacity.root.azkaban.state</name>
        <value>RUNNING</value>
  </property>

    可以看到,三個子隊列分配的資源佔比分別是:root.default 20、root.bigdataU 40、root.azkaban 40,這樣,在資源足夠的情況下三個隊列按照1:2:2的比例共享整個集羣資源。但是,容量調度器本身提供“彈性隊列”的性質,“彈性隊列”指的是,如果一個隊列的資源不足,同時系統又有空閒資源,那麼這個隊列所申請的資源可能會超過設定的資源佔比。

    但是這樣存在一個問題,A隊列分配了40%的資源,B隊列分配了60%的資源,如果A隊列此時使用資源很少,B隊列資源不夠,那麼B隊列就會搶佔A隊列的資源,後來,A隊列資源不足,雖然A隊列資源佔比40%,但是實際得到的資源可能不足這個比例,因爲資源都被B隊列搶走,那麼此時A隊列的任務只能等待B隊列執行完釋放資源。

    爲了避免資源不被其他隊列過多侵佔,我們可以設置一個隊列的最大容量限制(yarn.scheduler.capacity.<queue-path>.maximum-capacity),如上面的配置信息,root.azkaban雖然資源佔比40%,但是在某種情況下(該隊列資源緊張,集羣資源充足),該隊列的資源佔比最高可以達到45%,要說明的是,如果一個隊列沒有配置maximum-capacity,那麼理論上這個隊列可以佔用整個集羣資源的100%(子隊列需要看父隊列的資源佔比和最大資源佔比限制)。

打開YARN的web控制檯可以看到,使用的資源調度器是Capacity,主隊列root,下面有三個子隊列,顯示有資源佔比、最大資源佔比等配置信息。

三、隊列放置

    執行應用的時候,放在哪一個隊列取決於應用本身,需要應用自己指定,如果隊列不存在,則會拋異常,如果不指定隊列,那麼應用將被放在隊列名爲default的默認隊列中。如下圖我執行一個WordCount任務,但是沒有指定使用哪一個隊列:

在MapReduce任務中,指定隊列可以使用參數mapreduce.job.queuename參數,設置一個隊列名。需要注意的是,隊列名是隊列層級的最後一部分,例如我向指定到隊列roor.bigdataU,那麼參數需要使用bigdataU。

下面我指定隊列再跑一次:

hadoop jar ~/app/hadoop-2.6.0-cdh5.7.0/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0-cdh5.7.0.jar wordcount -D mapreduce.job.queuename=bigdataU /hadoop_test.txt /output/

將一個MapReduce作業放到bigdataU隊列中,其參數爲:

Used Capacity:實際使用資源佔分配資源的比例

Absolute Used Capacity:實際使用資源佔整個集羣的資源比例

Absolute Capacity:分配資源佔比

Absolute Max Capacity:最大分配資源佔比

四、總結

    和公平調度器一樣,容量調度器允許長時間執行的大任務可以及時完成,同時又允許小任務能在合理的時間內返回結果。

    我們可以使用資源佔比小的隊列專門處理小任務,這樣保證在有大任務執行的時候,小任務能夠一提交就可以啓動。但是由於隊列容量是給這個隊列專門保留的,因此這個策略會降低整個集羣的利用率,也就是說,相對於FIFO,大任務執行的時間會變長。

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