1. 程式人生 > >YARN的公平排程器配置。

YARN的公平排程器配置。

        公平排程器旨在為所有執行的應用公平分配資源。

        接下來解釋資源是如何在佇列之間公平共享的。想象兩個使用者A和B,分別擁有自己的佇列。A啟動一個作業,在B沒有需求時A會分配到全部可用資源;當A的作業仍在執行時B啟動一個作業,一段時間後,按照我們先前看到的方式,每個作業都用到了一半的叢集資源。這時,如果B啟動第二個做作業且其他作業仍在執行,那麼第二個作業將和B的其他作業(這裡是第一個)共享資源,因此B的每個作業將佔四分之一的叢集資源,而A仍繼續佔用一半的叢集資源。最終的結果就是資源在使用者之間實現了公平共享。

啟用公平排程器

        公平排程器的使用由屬性yarn.resourcemanager.scheduler.class的設定所決定。預設是使用容量排程器(儘管在一些Hadoop分散式專案,如CDH中是預設使用公平排程器),如果要使用公平排程器,需要將yarn-site.xml檔案中的yarn.resourcemanager.scheduler.class設定為公平排程器的完全限定名:org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler。

佇列配置

        通過一個名為fair-scheduler.xml的分配檔案對公平排程器進行配置,該檔案位於類路徑下。(可以通過設定屬性yarn.scheduler.fair.allocation.file來修改檔名)。當沒有該分配檔案時,公平排程器的工作策略同先前所描述的一樣:每個應用放置在一個以使用者名稱命名的佇列中,佇列是在使用者提交第一個應用時動態建立的。

        通過分配檔案可以為每個佇列進行配置。這樣可以對容量排程器支援的層次佇列進行分配。例如,可以像為容量排程器所做的那樣,使用下面範例所示的分配檔案定義prod和dev。

<?xml version="1.0"?>

<allocations>

<defaultQueueSchedulingPolicy>fair</defaultQueueSchedulingPolicy>

<queue name="prod">

<weight>40</weight>

<schedulingPolicy>fifo</schedulingPolicy>

</queue>

<queue name="dev">

<weight>60</weight>

<queue name = "eng" />

<queue name = "science" />

</queue>

<queuePlacementPolicy>

<rule name="specified" create="false" />

<rule name="primaryGroup" create="false"/>

<rule name="default" queue="dev.eng" />

</queuePlacementPolicy>

</allocations>

        佇列的層次使用巢狀queue元素來定義。所有的佇列都是root佇列的孩子,即使實際上並沒有巢狀進root queue元素裡。這裡把dev佇列又劃分成eng和science兩個佇列。

        佇列中有權重元素,用於公平共享計算。在這個例子中,當叢集資源按照40:60的比例分配給prod和dev時,叢集分配被認為是公平的。eng和science佇列沒有指定權重,因此他們會被平均分配。權重並不是百分百,例子中是為了簡單起見使用了相加之和為100的兩個數。也可以為prod和dev佇列分別指定2和3的權重,在效果是一樣的。

注意:當設定權重時,記住要考慮預設佇列和動態建立的佇列(例如以使用者名稱命名的佇列)。雖然沒有在分配檔案中為他們指定權重,但他們仍有值為1的權重。

        每個佇列可以有不同的排程策略。佇列的預設排程策略可以通過頂層元素defaultQueueSchedulingPolicy進行設定,如果省略,預設使用公平排程。儘管名稱是“公平”,公平排程器也支援佇列級別的FIFO(fifo)策略,以及Dominant Resource Fairness(drf)策略。

        佇列的排程策略可以被該佇列的schedulingPolicy元素指定的策略覆蓋。在上述例子中,由於我們希望每個生產性作業能夠順序執行且在最短可能的時間內結束,所以prod對壘使用了FIFO排程策略。值得注意的是,在prod和dev佇列之間、eng和science佇列之間及內部劃分資源仍然使用了公平排程。

        儘管上述的分配檔案中沒有展示,每個佇列仍可配置最大和最小資源數量,及最大可執行的應用的數量。最小資源數量不是一個硬性的限制,但是排程器常用他對資源分配進行優先排序。如果兩個佇列的資源都低於他們的公平共享額度,那麼遠低於最小資源數量的那個佇列優先被分配資源。最小資源數量也會用於搶佔行為。

佇列放置

        公平排程器使用一個基於規則的系統來確定應用應該放到哪個佇列。在上面範例中,queuePlacementPolicy元素包含了一個規則列表,每條規則會被依次嘗試直到匹配成功。

  • specified,表示把應用放進指明的佇列中,如果沒有指明,或如果所指明的佇列不存在,則規則不匹配,繼續嘗試下一條規則。
  • primaryGroup,會試著把應用放在以使用者的主Unix組名命名的佇列中,如果沒有這樣的佇列,則繼續嘗試下一條規則而不是建立佇列。
  • Default,是一條兜底規則,當前述規則都不匹配時,將啟用該條規則,把應用放進dev.eng佇列中。

        當然,可以完全省略queuePlacementPolicy元素,此時佇列放置預設遵守如下規則:

<queuePlacementPlicy>

<rule name = "specified" />

<rule name = "user"/>

</queuePlacementPlicy>

        換而言之,除非明確定義佇列,否則必要時會以使用者名稱為佇列列名建立佇列。

        另一個簡單地佇列放置策略是,將所有的應用放進同一佇列(default)中。這樣可以在應用之間公平共享資源,而不是在使用者之間共享。策略定義等價於以下規則:

<queuePlacementPlicy>

<rule name = "default" />

</queuePlacementPlicy>

        不使用分配檔案也可以設定以上策略,通過將屬性yarn.scheduler.fair.user-as-default-queue設定為false,應用就會被放入default佇列,而不是各個使用者的佇列。另外,將屬性yarm.scheduler.fair.allow-undeclared-pool設定為false,使用者便不能隨意建立隊列了。

搶佔

        在一個繁忙的叢集中,當作業被提交給一個空佇列時,作業不會立刻啟動,直到叢集上已經執行的作業釋放了資源。為了使作業從提交到執行所需的時間可預測,公平排程器支援“搶佔”(preemption)功能。

        所謂搶佔,就是允許排程器終止那些佔用資源超過了其公平共享份額的佇列的容器,這些容器資源釋放後可以分配給資源數量低於應得份額的佇列。注意,搶佔會降低整個叢集的效率,因為被終止的containers需要重新執行。

        通過將yarn.scheduler.fair.preemption設定為true,可以全面啟用搶佔功能。有兩個相關的搶佔超時設定:一個用於最小共享(minimum share preemption timeout),另一個用於公平共享(fair share preemption timeout),兩者設定時間均為秒級。預設情況下,兩個超時引數均不設定。所以為了允許搶佔容器,需要至少設定其中一個超時引數。

        如果佇列在minimum share preemption timeout指定的時間內未獲得被承諾的最小共享資源,排程器就會搶佔其他容器。可以通過分配檔案中的頂層元素defaultMinSharePreemptionTimeout為所有佇列設定預設的超時時間,還可以通過設定每個佇列的minSharePreemptionTimeout元素來為單個佇列指定超時時間。

        類似,如果佇列在fair share preemption timeout指定的時間內獲得的資源仍然地域其公平共享份額的一半,那麼排程器就會搶佔其他容器。可以通過分配檔案中的頂層元素defaultFairSharePreemptionTimeout為所有佇列設定預設的超時時間,還可以通過設定每個佇列的fairSharePreemptionTimeout元素來為單個佇列指定超時時間。通過設定defaultFairSharePreemptionThreshold和fairSharePreemptionThreshold(針對每個佇列)可以修改超時閾值,預設值是0.5。