配置限制

概觀

YARN 允許應用程式以資料區域性(偏好特定節點或機架)或(非重疊)節點標籤的形式指定配置限制。本文檔著重於 YARN 中更具表現力的配置限制。此類限制對於應用程式的效能和復原力至關重要,特別是那些包含長時間執行容器的應用程式,例如服務、機器學習和串流工作負載。

例如,將工作配置配置在同一機架上(親和性限制)以減少網路成本、將配置分散在多台機器上(反親和性限制)以最小化資源干擾,或允許在節點群組中最多指定數量的配置(基數限制)以在兩者之間取得平衡,可能是很有利的。配置決策也會影響復原力。例如,放置在同一群集升級網域內的配置將同時離線。

應用程式可以指定限制,而不需要知道叢集的底層拓撲(例如,不需要指定容器應該放置在哪個特定節點或機架,或已部署的其他應用程式)。目前,所有限制都是硬性限制,也就是說,如果容器的限制無法滿足,因為目前的叢集狀況或衝突的限制,容器要求將保持待處理或被拒絕。

請注意,在本文檔中,我們使用「配置」的概念來指稱在節點中配置的資源單位(例如,CPU 和記憶體)。在 YARN 的目前實作中,配置對應到單一容器。但是,如果應用程式使用配置來產生多個容器,配置可以對應到多個容器。

快速指南

我們首先說明如何啟用具有配置限制的排程,然後提供使用分散式 shell 的範例,說明如何使用此功能進行實驗,分散式 shell 是一個允許在容器組上執行特定 shell 命令的應用程式。

啟用配置限制

若要啟用配置限制,必須將下列屬性設定為 conf/yarn-site.xml 中的 placement-processorscheduler

屬性 說明 預設值
yarn.resourcemanager.placement-constraints.handler 指定將用於處理配置限制的處理常式。可接受的值為:placement-processorschedulerdisabled disabled

我們現在提供三個配置限制處理常式的更多詳細資訊

  • placement-processor:使用此處理常式,帶有限制的容器配置會在呼叫容量或公平排程器之前,視為預處理步驟來決定。一旦決定配置,就會呼叫容量/公平排程器來執行實際配置。此處理常式的優點是它支援所有限制類型(親和性、反親和性、基數)。此外,它一次考慮多個容器,這允許滿足比一次一個容器方法所能達成的更多限制。由於它位於主排程器之外,因此容量排程器和公平排程器都可以使用它。請注意,目前它不會考量應用程式中的工作優先順序,因為此類優先順序可能會與配置限制衝突。
  • scheduler:使用此處理常式,帶有限制的容器將由主排程器配置(目前,只有容量排程器支援排程要求)。它目前支援反親和性限制(沒有親和性或基數)。與 placement-processor 相比,此處理常式的優點是它遵循現有主排程器強制執行的佇列(依使用率、優先順序排序)、應用程式(依 FIFO/公平性/優先順序排序)和同一個應用程式中的工作(優先順序)的相同排序規則。
  • disabled:使用此處理常式,如果應用程式要求排程要求,將拒絕對應的配置呼叫。

placement-processor 處理常式支援更廣泛的限制,並且允許配置更多容器,特別是在應用程式有嚴格限制或叢集使用率很高的時候(因為一次考慮多個容器)。但是,如果尊重應用程式中的工作優先順序對使用者很重要,並且使用容量排程器,則應該改用 scheduler 處理常式。

使用分布式 shell 測試配置限制

使用者可以使用分布式 shell 應用程式透過下列指令測試配置限制

$ yarn org.apache.hadoop.yarn.applications.distributedshell.Client -jar share/hadoop/yarn/hadoop-yarn-applications-distributedshell-3.3.6.jar -shell_command sleep -shell_args 10 -placement_spec PlacementSpec

其中 PlacementSpec 的格式為

PlacementSpec               => "" | PlacementExpr;PlacementSpec
PlacementExpr               => SourceTag,ConstraintExpr
SourceTag                   => String(NumContainers)
ConstraintExpr              => SingleConstraint | CompositeConstraint
SingleConstraint            => "IN",Scope,TargetTag | "NOTIN",Scope,TargetTag | "CARDINALITY",Scope,TargetTag,MinCard,MaxCard | NodeAttributeConstraintExpr
NodeAttributeConstraintExpr => NodeAttributeName=Value, NodeAttributeName!=Value
CompositeConstraint         => AND(ConstraintList) | OR(ConstraintList)
ConstraintList              => Constraint | Constraint:ConstraintList
NumContainers               => int
Scope                       => "NODE" | "RACK"
TargetTag                   => String
MinCard                     => int
MaxCard                     => int

注意

  • 在分布式 shell 指令中指定 -placement_spec 參數(NodeAttributeConstraintExpr 除外)時,不應使用 -num-containers 參數。如果 -num-containers 參數與 -placement-spec 一起使用,將會忽略前者。這是因為在 PlacementSpec 中,我們會決定每個標籤的容器數量,這使得 -num-containers 變得多餘且可能產生衝突。此外,如果使用 -placement_spec,所有容器都將要求保證執行類型。
  • 如果指定 NodeAttributeConstraintExpr,則 SourceTag(NumContainers) 是選用的,且 -num-containers 的值將被視為要要求的容器數量。

PlacementSpec 的範例如下

zk(3),NOTIN,NODE,zk:hbase(5),IN,RACK,zk:spark(7),CARDINALITY,NODE,hbase,1,3

上述編碼三個限制

  • 將 3 個標籤為「zk」(代表 ZooKeeper)的容器置於彼此具有節點反親和性的節點,亦即每個節點不得放置超過一個容器(請注意,在此第一個限制中,限制的 SourceTag 和 TargetTag 相同);
  • 將 5 個標籤為「hbase」的容器置於執行標籤為「zk」的容器的機架上(亦即「hbase」容器不應放置在執行「zk」容器的機架上,因為「zk」是第二個限制的 TargetTag);
  • 將 7 個標籤為「spark」的容器置於具有至少一個但不多於三個標籤為「hbase」的容器的節點中。

以下另一個範例示範複雜形式的限制

zk(5),AND(IN,RACK,hbase:NOTIN,NODE,zk)

上述限制使用連接詞 AND 來結合兩個限制。當其兩個子限制都符合時,AND 限制才符合。特定的 PlacementSpec 要求將 5 個「zk」容器置於執行至少一個「hbase」容器的機架上,且置於未執行任何「zk」容器的節點上。類似地,可以使用 OR 運算子來定義一個限制,當其至少一個子限制符合時才符合。請注意,如果「zk」和「hbase」是屬於不同應用程式的容器(在實際使用案例中很可能是這樣),PlacementSpec 中的配置標籤應包含命名空間,如下所述(請參閱 配置標籤命名空間)。

定義配置限制

配置標籤

配置標籤是應用程式可以與其容器(群組)關聯的字串標籤。標籤用於識別應用程式組件。例如,HBase Master 配置可以標記為「hbase-m」,而區域伺服器則標記為「hbase-rs」。其他範例包括「latency-critical」用於指涉配置的更一般需求,或「app_0041」用於表示工作 ID。配置標籤在限制中扮演關鍵角色,因為它們允許參照共享共同標籤的多個配置。

請注意,我們使用新的 SchedulingRequest 物件來定義配置標籤,而不是使用 ResourceRequest 物件。這與 ResourceRequest 有許多相似之處,但更能區分請求配置的大小(配置數量和大小、優先順序、執行類型等)和約束條件,說明這些配置應如何配置(資源名稱、放寬的區域性)。應用程式仍可以使用 ResourceRequest 物件,但為了定義配置標籤和約束條件,他們需要使用 SchedulingRequest 物件。在單一 AllocateRequest 中,應用程式應使用 ResourceRequestSchedulingRequest 物件,但不能同時使用這兩個物件。

配置標籤命名空間

配置標籤可能參考相同或不同應用程式的容器,並分別用於表達應用程式內部或應用程式之間的約束條件。我們使用配置標籤命名空間來指定配置標籤可以參考的應用程式範圍。透過將配置標籤與命名空間結合,我們可以限制標籤是否針對屬於相同應用程式、特定應用程式群組或叢集中的任何應用程式的容器。

我們目前支援下列命名空間

命名空間 語法 說明
SELF self/${allocationTag} 配置標籤參考目前應用程式的容器(約束條件將套用於該容器)。這是預設命名空間。
NOT_SELF not-self/${allocationTag} 配置標籤僅參考不屬於目前應用程式的容器。
ALL all/${allocationTag} 配置標籤參考任何應用程式的容器。
APP_ID app-id/${applicationID}/${allocationTag} 配置標籤參考具有指定應用程式 ID 的應用程式的容器。
APP_TAG app-tag/application_tag_name/${allocationTag} 配置標籤參考標記有指定應用程式標籤的應用程式的容器。

若要將配置標籤命名空間 ns 附加到目標標籤 targetTag,我們在 PlacementSpec 中使用語法 ns/allocationTag。請注意,預設命名空間為 SELF,用於應用程式內部約束條件。其餘命名空間標籤用於指定應用程式之間約束條件。當命名空間未指定在標籤旁邊時,會假設為 SELF

上面使用的範例約束條件可以用命名空間延伸如下

zk(3),NOTIN,NODE,not-self/zk:hbase(5),IN,RACK,all/zk:spark(7),CARDINALITY,NODE,app-id/appID_0023/hbase,1,3

這些約束條件的語意如下

  • 將 3 個標籤為「zk」(代表 ZooKeeper)的容器配置到沒有執行其他應用程式「zk」容器的節點;
  • 將 5 個標籤為「hbase」的容器配置到具有標籤為「zk」(來自任何應用程式,無論是相同或不同的應用程式)的容器執行的機架的親和性;
  • 將 7 個標記為「spark」的容器放置在至少有一個,但不多於三個標記為「hbase」的容器的節點中,這些容器屬於 ID 為 appID_0023 的應用程式。

節點標籤、節點屬性和配置標籤之間的差異

配置標籤與節點標籤或 節點屬性 之間的差異在於配置標籤附加到配置,而不是節點。當配置由排程器配置到節點時,該配置的標籤組會在配置期間自動新增到節點。因此,節點會繼承目前配置到該節點的配置標籤。同樣地,機架會繼承其節點的標籤。此外,與節點標籤類似,但與節點屬性不同,配置標籤沒有附加的任何值。如下所示,我們的限制條件可以參考配置標籤,以及節點標籤和節點屬性。

配置限制條件 API

應用程式可以使用 PlacementConstraints 中的公開 API 來建構配置限制條件。在說明建構限制條件的方法之前,我們將說明 PlacementTargets 類別的方法,這些方法用於建構目標表達式,然後在限制條件中使用這些表達式

方法 說明
allocationTag(String... allocationTags) 在配置標籤上建構目標表達式。如果存在具有其中一個指定標籤的配置,則滿足此表達式。
allocationTagWithNamespace(String namespace, String... allocationTags) 類似於 allocationTag(String...),但允許為指定的配置標籤指定名稱空間。
nodePartition(String... nodePartitions) 在節點分割區上建構目標表達式。對於屬於其中一個 nodePartitions 的節點,此表達式會成立。
nodeAttribute(String attributeKey, String... attributeValues) 在節點屬性上建構目標表達式。如果指定的節點屬性具有其中一個指定的值,則滿足此表達式。

請注意,上述 nodeAttribute 方法尚未運作,因為它需要持續的節點屬性功能。

PlacementConstraints 類別用於建構限制條件的方法如下

方法 說明
targetIn(String scope, TargetExpression... targetExpressions) 建立限制條件,要求配置放置在滿足指定範圍內所有目標表達式的節點上(例如,節點或機架)。例如,targetIn(RACK, allocationTag("hbase-m")) 允許配置在屬於具有至少一個標記為「hbase-m」的配置的機架上的節點上。
targetNotIn(String scope, TargetExpression... targetExpressions) 建立一個限制,要求配置必須放置在不滿足任何目標表達式的範圍(例如,節點或機架)所屬的節點上。
cardinality(String scope, int minCardinality, int maxCardinality, String... allocationTags) 建立一個限制,限制特定範圍(例如,節點或機架)內的配置數量。例如,{@code cardinality(NODE, 3, 10, “zk”)} 在節點上滿足,其中具有標籤「zk」的配置不少於 3 個且不超過 10 個。
minCardinality(String scope, int minCardinality, String... allocationTags) 類似於 cardinality(String, int, int, String...),但僅確定最小基數(最大基數未繫結)。
maxCardinality(String scope, int maxCardinality, String... allocationTags) 類似於 cardinality(String, int, int, String...),但僅確定最大基數(最小基數為 0)。
targetCardinality(String scope, int minCardinality, int maxCardinality, String... allocationTags) 此限制概括了基數和目標限制。考慮屬於限制中指定範圍的節點集 N。如果目標表達式在節點集 N 中至少滿足 minCardinality 次且最多滿足 maxCardinality 次,則滿足限制。例如,targetCardinality(RACK, 2, 10, allocationTag("zk")),需要將配置放置在機架中,該機架具有至少 2 個且最多 10 個其他具有標籤「zk」的配置。

PlacementConstraints 類別還包括用於建立複合限制的方法(具有多個限制的 AND/OR 表達式)。增加對複合限制的支持正在進行中。

在應用程式中指定限制

應用程式必須指定將為其啟用每個限制的容器。為此,應用程式可以提供從一組配置標籤(來源標籤)到配置限制的對應。例如,此對應的條目可以是「hbase」->constraint1,這表示在排程具有標籤「hbase」的每個配置時,將套用 constraint1。

使用 placement-processor 處理常式時(請參閱 啟用配置限制),此限制對應會在 RegisterApplicationMasterRequest 中指定。

使用 scheduler 處理常式時,也可以在每個 SchedulingRequest 物件中新增限制。每個此類限制都對該排程要求的標籤有效。如果在 RegisterApplicationMasterRequest 和排程要求中都指定了限制,則後者會覆寫前者。