YARNでは、アプリケーションはデータローカリティ(特定のノードまたはラックを優先)または(重複しない)ノードラベルの形式で配置制約を指定できます。このドキュメントでは、YARNでのより表現力豊かな配置制約に焦点を当てています。このような制約は、特にサービス、機械学習、ストリーミングワークロードなど、長時間実行されるコンテナを含むアプリケーションのパフォーマンスと回復力にとって重要です。
たとえば、ネットワークコストを削減するためにジョブの割り当てを同じラックに配置(アフィニティ制約)、リソースの干渉を最小限に抑えるために割り当てをマシン全体に分散(アンチアフィニティ制約)、または2つのバランスを取るためにノードグループ内の割り当て数を特定の上限まで許可する(カーディナリティ制約)ことが有益な場合があります。配置の決定は回復力にも影響します。たとえば、同じクラスタアップグレードドメイン内に配置された割り当ては、同時にオフラインになります。
アプリケーションは、クラスタの基礎となるトポロジ(たとえば、コンテナを配置する特定のノードまたはラックを制約で指定する必要はありません)またはデプロイされた他のアプリケーションの知識を必要とせずに制約を指定できます。現在、すべての制約はハードです。つまり、現在のクラスタの状態または競合する制約によりコンテナの制約を満たすことができない場合、コンテナ要求は保留中になるか、拒否されます。
このドキュメントでは、「割り当て」という概念を、ノードに割り当てられるリソース(CPUやメモリなど)の単位を指すために使用していることに注意してください。現在のYARNの実装では、割り当ては単一のコンテナに対応します。ただし、アプリケーションが1つの割り当てを使用して複数のコンテナを生成する場合、割り当ては複数のコンテナに対応する可能性があります。
最初に、配置制約を使用したスケジューリングを有効にする方法について説明し、次に、分散シェルを使用してこの機能を実験する方法の例を提供します。分散シェルは、一連のコンテナで特定のシェルコマンドを実行できるアプリケーションです。
配置制約を有効にするには、conf/yarn-site.xmlで次のプロパティをplacement-processor
またはscheduler
に設定する必要があります。
プロパティ | 説明 | デフォルト値 |
---|---|---|
yarn.resourcemanager.placement-constraints.handler |
PlacementConstraintsの処理に使用されるハンドラーを指定します。使用可能な値は、placement-processor 、scheduler 、およびdisabled です。 |
disabled |
次に、3つの配置制約ハンドラーのそれぞれについて詳しく説明します。
placement-processor
:このハンドラーを使用すると、制約のあるコンテナの配置は、キャパシティまたはフェアスケジューラーが呼び出される前の前処理ステップとして決定されます。配置が決定されると、キャパシティ/フェアスケジューラーが呼び出され、実際の割り当てが実行されます。このハンドラーの利点は、すべての制約タイプ(アフィニティ、アンチアフィニティ、カーディナリティ)をサポートしていることです。さらに、一度に複数のコンテナを考慮するため、コンテナごとのアプローチよりも多くの制約を満たすことができます。メインスケジューラーの外部にあるため、キャパシティスケジューラーとフェアスケジューラーの両方で使用できます。現時点では、そのような優先度が配置制約と競合する可能性があるため、アプリケーション内のタスクの優先度を考慮していないことに注意してください。scheduler
:このハンドラーを使用すると、制約のあるコンテナはメインスケジューラーによって配置されます(現時点では、キャパシティスケジューラーのみがSchedulingRequestsをサポートしています)。現在、アンチアフィニティ制約をサポートしています(アフィニティまたはカーディナリティはサポートしていません)。このハンドラーの利点は、placement-processor
と比較して、既存のメインスケジューラーによって適用されるキュー(利用率、優先度でソート)、アプリ(FIFO/公平性/優先度でソート)、および同じアプリ内のタスク(優先度)の同じ順序付けルールに従うことです。disabled
:このハンドラーを使用すると、アプリケーションによってSchedulingRequestが要求された場合、対応する割り当て呼び出しは拒否されます。placement-processor
ハンドラーは、より広範囲の制約をサポートし、特にアプリケーションに厳しい制約がある場合やクラスタが高度に利用されている場合(一度に複数のコンテナを考慮するため)、より多くのコンテナを配置できます。ただし、アプリケーション内のタスクの優先度を尊重することがユーザーにとって重要であり、キャパシティスケジューラーを使用する場合は、代わりにscheduler
ハンドラーを使用する必要があります。
ユーザーは、次のコマンドを使用して分散シェルアプリケーションを使用することで、配置制約を実験できます。
$ 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
注意
-placement_spec
引数が指定されている場合(NodeAttributeConstraintExprを除く)、-num-containers
引数を使用しないでください。-num-containers
引数が-placement-spec
と組み合わせて使用されている場合、前者は無視されます。これは、PlacementSpecではタグごとのコンテナ数を決定するため、-num-containers
が冗長であり、競合する可能性があるためです。さらに、-placement_spec
が使用されている場合、すべてのコンテナはGUARANTEED実行タイプで要求されます。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(5),AND(IN,RACK,hbase:NOTIN,NODE,zk)
上記の制約では、2つの制約を組み合わせるために接続演算子AND
を使用しています。AND制約は、その両方の子制約が満たされた場合に満たされます。特定のPlacementSpecでは、少なくとも1つの「hbase」コンテナが実行されているラックで、かつ「zk」コンテナが実行されていないノードで5つの「zk」コンテナを配置するように要求します。同様に、OR
演算子を使用して、少なくとも1つの子制約が満たされた場合に満たされる制約を定義できます。「zk」と「hbase」が異なるアプリケーションに属するコンテナである場合(これは実際のユースケースで最も可能性が高い)、PlacementSpecのアロケーションタグには、以下で説明するように、名前空間を含める必要があります(アロケーションタグの名前空間を参照)。
アロケーションタグは、アプリケーションが(グループの)コンテナに関連付けることができる文字列タグです。タグは、アプリケーションのコンポーネントを識別するために使用されます。たとえば、HBase Master割り当てには「hbase-m」、Region Serversには「hbase-rs」というタグを付けることができます。その他の例として、割り当てのより一般的な要求を指す「レイテンシクリティカル」、またはジョブIDを表す「app_0041」があります。アロケーションタグは、共通のタグを共有する複数の割り当てを参照できるため、制約において重要な役割を果たします。
アロケーションタグを定義するために ResourceRequest
オブジェクトを使用する代わりに、新しい SchedulingRequest
オブジェクトを使用することに注意してください。これには ResourceRequest
と多くの類似点がありますが、要求されたアロケーションのサイズ(アロケーションの数とサイズ、優先度、実行タイプなど)と、これらのアロケーションをどのように配置するかを指示する制約(リソース名、緩和された局所性)がより適切に分離されています。アプリケーションは引き続き ResourceRequest
オブジェクトを使用できますが、アロケーションタグと制約を定義するためには、SchedulingRequest
オブジェクトを使用する必要があります。単一の AllocateRequest
内では、アプリケーションは ResourceRequest
オブジェクトまたは SchedulingRequest
オブジェクトのどちらかを使用する必要がありますが、両方を使用することはできません。
アロケーションタグは、同じまたは異なるアプリケーションのコンテナを参照することができ、それぞれアプリケーション内またはアプリケーション間の制約を表すために使用されます。アロケーションタグが参照できるアプリケーションのスコープを指定するために、アロケーションタグの名前空間を使用します。アロケーションタグを名前空間と組み合わせることで、タグが同じアプリケーションに属するコンテナ、特定のアプリケーショングループに属するコンテナ、またはクラスタ内の任意のアプリケーションに属するコンテナを対象とするかどうかを制限できます。
現在、次の名前空間をサポートしています。
名前空間 | 構文 | 説明 |
---|---|---|
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
これらの制約の意味は次のとおりです。
appID_0023
のアプリケーションに属する "hbase" タグを持つコンテナが少なくとも 1 つ、最大 3 つあるノードに、"spark" タグを持つ 7 つのコンテナを配置します。アロケーションタグとノードラベルまたはノード属性の違いは、アロケーションタグがノードではなくアロケーションにアタッチされることです。スケジューラによってアロケーションがノードに割り当てられると、そのアロケーションのタグセットがアロケーションの期間中、自動的にノードに追加されます。したがって、ノードは現在ノードに割り当てられているアロケーションのタグを継承します。同様に、ラックはそのノードのタグを継承します。さらに、ノードラベルと同様に、ノード属性とは異なり、アロケーションタグには値がアタッチされていません。以下に示すように、制約はアロケーションタグだけでなく、ノードラベルやノード属性も参照できます。
アプリケーションは、配置制約を構築するために 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" タグを持つアロケーションが少なくとも1つあるラックに属するノードのアロケーションを許可します。 |
targetNotIn(String scope, TargetExpression... targetExpressions) |
いずれのターゲット式も満たさないスコープ(例:ノードまたはラック)に属するノードにアロケーションを配置する必要がある制約を作成します。 |
cardinality(String scope, int minCardinality, int maxCardinality, String... allocationTags) |
指定されたスコープ(例:ノードまたはラック)内のアロケーション数を制限する制約を作成します。たとえば、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")) では、"zk" タグを持つ他のアロケーションが少なくとも 2 つ、最大で 10 個あるラック内にアロケーションを配置する必要があります。 |
PlacementConstraints
クラスには、複合制約(複数の制約を持つ AND/OR 式)を構築するためのメソッドも含まれています。複合制約のサポートの追加は進行中です。
アプリケーションは、各制約が有効になるコンテナを指定する必要があります。このために、アプリケーションはアロケーションタグのセット(ソースタグ)から配置制約へのマッピングを提供できます。たとえば、このマッピングのエントリは "hbase"->constraint1 であり、これは "hbase" タグを持つ各アロケーションをスケジュールするときに constraint1 が適用されることを意味します。
placement-processor
ハンドラを使用する場合(配置制約の有効化を参照)、この制約マッピングは RegisterApplicationMasterRequest
内で指定されます。
scheduler
ハンドラを使用する場合、制約は各 SchedulingRequest
オブジェクトに追加することもできます。このような各制約は、そのスケジュール要求のタグに対して有効です。制約が RegisterApplicationMasterRequest
とスケジュール要求の両方で指定されている場合、後者が前者をオーバーライドします。