機会的コンテナー

目的

このドキュメントでは、**機会的**コンテナー実行の概念を紹介し、機会的コンテナーの割り当てと実行方法について説明します。

クイックガイド

まず、ユーザーがこの機能を有効にして、そのようなコンテナーを使用してサンプルジョブを実行する方法を含め、機会的コンテナーの概要を簡単に説明します。

主な目標

ノードに未割り当てのリソースがある場合にのみスケジュールされる既存のYARNコンテナーとは異なり、機会的コンテナーは、そのノードでの実行がすぐに開始できない場合でも、NMにディスパッチできます。 そのような場合、機会的コンテナーは、リソースが利用可能になるまで、そのNMでキューに入れられます。 機会的コンテナー実行の主な目標は、クラスタリソースの利用率を向上させ、タスクスループットを向上させることです。 リソース使用率とタスクスループットの向上は、比較的短いタスク(数秒程度)を含むワークロードでより顕著になります。

機会的コンテナーの有効化

機会的コンテナー割り当てを有効にするには、**conf/yarn-site.xml**に次の2つのプロパティが存在する必要があります。

プロパティ 説明 デフォルト値
yarn.resourcemanager.opportunistic-container-allocation.enabled 機会的コンテナー割り当てを有効にします。 false
yarn.nodemanager.opportunistic-containers-max-queue-length NMでキューに入れることができる機会的コンテナーの最大数を決定します。 0

上記の最初のパラメータは`true`に設定する必要があります。 2つ目は、NMで機会的コンテナーのキューイングを許可するには、正の値に設定する必要があります。 `10`の値を使用して、機会的コンテナーの実験を開始できます。 最適値は、ジョブの特性、クラスタ構成、および目標とする利用率によって異なります。

デフォルトでは、機会的コンテナーの割り当てはRMを介して集中して実行されます。 ただし、ユーザーは機会的コンテナーの分散割り当てを有効にすることを選択できます。これにより、短いタスクの割り当てレイテンシがさらに向上する可能性があります。 分散スケジューリングは、次のパラメータを`true`に設定することで有効にできます(非機会的コンテナーは引き続きRMを介してスケジュールされることに注意してください)。

プロパティ 説明 デフォルト値
yarn.nodemanager.distributed-scheduling.enabled 分散スケジューリングを有効にします。 false

AMRMProxyが有効になっているクラスタにジョブを送信するには、ジョブが送信されるクライアント用に個別の構成セットを作成する必要があります。 これらでは、**conf/yarn-site.xml**に次の追加構成が必要です

プロパティ 説明
yarn.resourcemanager.scheduler.address localhost:8049 ジョブをノードマネージャーのAMRMProxyポートにリダイレクトします。

サンプルジョブの実行

MapReduce PI

次のコマンドを使用して、サンプルのpi map-reduceジョブを実行し、マッパーの40%を機会的コンテナーを使用して実行できます。

$ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar pi -Dmapreduce.job.num-opportunistic-maps-percent="40" 50 100

上記のコマンドで`mapreduce.job.num-opportunistic-maps-percent`の値を変更することにより、機会的コンテナーで実行できるマッパーの割合を指定できます。

分散シェル

別のサンプルジョブは分散シェルです。これにより、指定されたシェルコマンドを一連のコンテナーで実行できます。 次のコマンドを使用して、10個の機会的コンテナーで`sleep 10`コマンドを実行できます。

$ yarn org.apache.hadoop.yarn.applications.distributedshell.Client -jar share/hadoop/yarn/hadoop-yarn-applications-distributedshell-3.3.6.jar.jar -shell_command sleep -shell_args 10 -num_containers 10 -container_type OPPORTUNISTIC

上記のコマンドで`container_type`の値を`OPPORTUNISTIC`または`GUARANTEED`に変更することにより、機会的コンテナーまたは保証されたコンテナーで実行するタスクを指定できます。 デフォルトのタイプは`GUARANTEED`です。 `-promote_opportunistic_after_start`フラグを上記のコマンドに追加することにより、アプリケーションマスターは、開始されたすべての機会的コンテナーを保証されたコンテナーに昇格しようとします。 `-enforce_execution_type`フラグを上記のコマンドに追加することにより、スケジューラはコンテナーの実行タイプを尊重します。

Web UIでの機会的コンテナー

機会的コンテナー割り当てが有効になっている場合、Web UI(`rm-address:8088/cluster/nodes`)の[ノード]ページに次の新しい列が表示されます。

  • 実行中のコンテナー(O):各ノードで実行されている機会的コンテナーの数。
  • 使用済みメモリ(O):各ノードの機会的コンテナーで使用されているメモリ合計。
  • 使用済みvCore(O):各ノードの機会的コンテナーで使用されているCPU仮想コアの合計数。
  • キューに入れられたコンテナー:各ノードでキューに入れられたコンテナーの数。

ノードで実行されている特定のコンテナーをクリックすると、コンテナーの実行タイプも表示されます。

ドキュメントの残りの部分では、割り当てと実行に関する詳細を含め、機会的コンテナーについて詳しく説明します。

概要

YARN(Fair SchedulerとCapacity Scheduler)の既存のスケジューラは、コンテナーのスケジュール時にそのノードに未割り当てのリソースがある場合にのみ、ノードにコンテナーを割り当てます。 この**保証された**実行タイプには、AMがコンテナーをノードにディスパッチすると、使用可能なリソースがあることが保証されているため、コンテナーの実行がすぐに開始されるという利点があります。 さらに、公平性または容量の制約に違反しない限り、コンテナーはプリエンプトされることなく完了まで実行されることが保証されます。

この設計は、より予測可能なタスク実行を提供しますが、クラスタリソースの利用率が最適にならない可能性がある2つの主な欠点があります。

  • **フィードバックの遅延。** コンテナがノードでの実行を完了すると、RMは次のNM-RMハートビートを通じて使用可能なリソースがあることを通知され、RMはそのノードに新しいコンテナをスケジュールし、AMは次のAM-RMハートビートを通じて通知され、最終的にAMはノードで新しいコンテナーを起動します。 これらの遅延により、ノードリソースがアイドル状態になり、特にワークロードに期間が比較的短いタスクが含まれる場合、リソース使用率が低下します。
  • **割り当て済みリソースと使用済みリソース。** RMは、各ノードの_割り当て済み_リソースに基づいてコンテナーを割り当てます。これは、実際に_使用されている_リソースよりも大幅に多い場合があります(たとえば、4GBのメモリが割り当てられているが、2GBのみが使用されているコンテナーを考えてみます)。 これにより、効果的なリソース使用率が低下し、RMがスケジューリング中に使用されているリソースを考慮に入れることで回避できます。 ただし、これは、実行中のコンテナーの使用済みリソースが増加した場合にリソースを再利用できるようにする方法で行う必要があります。

上記の問題を軽減するために、既存のコンテナ(以下、**保証付き**コンテナと呼ぶ)に加えて、**投機的**コンテナという概念を導入します。投機的コンテナは、スケジューリング時に利用可能な(未割り当ての)リソースがない場合でも、NMにディスパッチできます。このような場合、投機的コンテナはNMでキューに入れられ、実行開始に必要なリソースが利用可能になるのを待ちます。投機的コンテナは、保証付きコンテナよりも優先度が低いため、保証付きコンテナの実行を開始するためにプリエンプトされる可能性があります。したがって、既存の保証付きコンテナの実行に影響を与えることなく、クラスタリソースの利用率を向上させるために使用できます。

投機的コンテナのもう1つの利点は、**NMにおける実行優先度**の概念を導入することです。たとえば、厳密な実行保証を必要としない優先度の低いジョブは、タスクに投機的コンテナまたはコンテナ実行タイプの組み合わせを使用できます。

投機的コンテナを割り当てる2つの方法、**集中型**と**分散型**を導入しました。集中型スケジューリングでは、投機的コンテナはYARN RMを介して割り当てられますが、分散型スケジューリングでは、各NMに存在するローカルスケジューラを介して割り当てられます。集中型割り当てにより、より質の高い配置決定と、アプリケーション全体でより複雑な共有ポリシー(例:公平性)の実装が可能になります。一方、分散型スケジューリングは、RMへのラウンドトリップを回避するため、短いタスクに役立つ、より高速なコンテナ割り当てを提供できます。どちらの場合でも、保証付きコンテナのスケジューリングはそのまま残り、YARN RM(既存のFair SchedulerまたはCapacity Schedulerを使用)を介して行われます。

現在の実装では、割り当てられた(使用されていない)リソースに基づいてコンテナを割り当てていることに注意してください。したがって、上記の「フィードバック遅延」の問題は解決しますが、「割り当て済みリソースと使用済みリソース」の問題は解決しません。後者の問題にも対処するために、投機的コンテナを採用する作業(`YARN-1011`)が進行中です。

以下では、コンテナ実行タイプ、および投機的コンテナの実行(NMでのコンテナキューイングを含む)と割り当てについて詳しく説明します。次に、高度な構成パラメータを使用して投機的コンテナを微調整する方法について説明します。最後に、今後の作業項目について説明します。

コンテナ実行タイプ

次の2種類のコンテナを導入します。

  • **保証付きコンテナ**は、既存のYARNコンテナに対応します。Fair SchedulerまたはCapacity Schedulerによって割り当てられ、ノードにディスパッチされると、実行をすぐに開始するためのリソースが利用可能であることが保証されます。(障害が発生しない限り)これらのコンテナは完了まで実行されます。スケジューラのキューが公平性または容量の制約に違反した場合にのみ、プリエンプトされる可能性があります。
  • **投機的コンテナ**は、ノードにディスパッチされたときに実行を開始するためのリソースが必ずしも利用可能であるとは限りません。代わりに、リソースが利用可能になるまで、NMでキューに入れられる場合があります。保証付きコンテナがノードに到着し、利用可能なリソースがない場合、保証付きコンテナを実行するために1つ以上の投機的コンテナがプリエンプトされます。

AMがリソース要求をRMに送信すると、各コンテナのタイプ(デフォルトは保証付き)を指定し、コンテナの割り当て方法を決定します。その後、コンテナがNMでAMによって起動されると、そのタイプによってNMによる実行方法が決まります。

投機的コンテナの実行

コンテナがNMに到着すると、その実行は、NMの利用可能なリソースとコンテナタイプによって決定されます。保証付きコンテナはすぐに実行を開始し、必要に応じて、NMは実行中の投機的コンテナを強制終了して、保証付きコンテナが開始するのに十分なリソースがあることを確認します。一方、投機的コンテナは、NMに到着したときに実行を開始するためのリソースがない場合、NMでキューに入れられる可能性があります。これを可能にするために、各ノードでコンテナのキューイングを許可することで、NMを拡張しました。NMはローカルリソースを監視し、利用可能なリソースが十分にあると、キューの先頭にある投機的コンテナの実行を開始します。

具体的には、コンテナがNMに到着すると、ローカライゼーションが実行され(つまり、必要なすべてのリソースがダウンロードされます)、コンテナは`SCHEDULED`状態に移行します。この状態では、コンテナはキューに入れられ、実行の開始を待ちます。

  • 利用可能なリソースがある場合、コンテナの実行は、実行タイプに関係なくすぐに開始されます。
  • 利用可能なリソースがない場合
    • コンテナが保証付きの場合、保証付きコンテナを実行するために必要な数だけ実行中の投機的コンテナを強制終了し、実行を開始します。
    • コンテナが投機的である場合、リソースが利用可能になるまでキューに留まります。
  • コンテナ(保証付きまたは投機的)が実行を完了し、リソースが解放されると、キューに入れられたコンテナを調べ、利用可能なリソースがあれば実行を開始します。FIFO順にキューからコンテナを選択します。

以下の今後の作業項目では、タスク実行の優先順位付け(キューの再 ordering)と、保証付きコンテナのスペースを確保するための投機的コンテナの強制終了について、さまざまな方法について説明します。

投機的コンテナの割り当て

上記のように、投機的コンテナを割り当てる集中型と分散型の両方の方法を提供します。以下で説明します。

集中型割り当て

`ApplicationMasterService`を拡張する`OpportunisticContainerAllocatorAMService`という新しいサービスをRMに導入しました。集中型投機的割り当てが有効になっている場合、AMからのリソース要求はRM側で`OpportunisticContainerAllocatorAMService`によって処理され、2つのリソース要求セットに分割されます。

  • 保証付きセットは、既存の`ApplicationMasterService`に転送され、その後、Fair SchedulerまたはCapacity Schedulerによって処理されます。
  • 投機的セットは、投機的コンテナのノードへのスケジューリングを実行する新しい`OpportunisticContainerAllocator`によって処理されます。

`OpportunisticContainerAllocator`は、各時点でクラスタの負荷の最も低いノードのリストを保持し、ラウンドロビン方式でコンテナを割り当てます。現在の実装では、ノードの局所性制約を意図的に考慮していないことに注意してください。投機的コンテナは(保証付きコンテナとは異なり)実行が開始される前にNMのキューで待機する可能性があるため、局所性制約を尊重するよりも、負荷の低いノード(つまり、キューイング遅延が小さいノード)に割り当てる方が重要です。さらに、現時点では、投機的コンテナに対する共有(公平性/容量)制約は考慮していません。必要に応じて、局所性と共有の両方の制約のサポートを将来追加できます。

分散型割り当て

投機的コンテナの分散スケジューリングを可能にするために、`AMRMProxyService`と呼ばれる新しいサービスを各NMに導入しました。`AMRMProxyService`は`ApplicationMasterService`プロトコルを実装し、そのノードで実行されているAMとRMの間のプロキシとして機能します。`AMRMProxyService`が(パラメータを介して)有効になっている場合、特定のノードで実行されているすべてのAMは、RMに直接アクセスする代わりに、同じノードの`AMRMProxyService`と通信するように強制されます。さらに、AMがRMと直接通信しないようにするために、新しいAMが初期化されると、その`AMRMToken`を`AMRMProxyService`によって署名されたトークンに置き換えます。

インターセプターのチェーンを`AMRMProxyService`に登録できます。これらのインターセプターの1つは、RMに連絡することなく、分散方式で投機的コンテナを割り当てる役割を担う`DistributedScheduler`です。このモジュール設計により、`AMRMProxyService`は、YARNフェデレーション(`YARN-2915`)や、不正な動作をするAMの調整など、他のシナリオでも役立ちます。これらは、インターセプターチェーンに追加のインターセプターを追加するだけで有効にできます。

分散投機的スケジューリングが有効になっている場合、各AMはリソース要求を同じノードで実行されている`AMRMProxyService`に送信します。`AMRMProxyService`は、リソース要求を2つのセットに分割します。

  • 保証付きセットはRMに転送されます。この場合、`AMRMProxyService`は単にAMとRMの間のプロキシとして機能し、コンテナの割り当てはそのまま残ります(Fair SchedulerまたはCapacity Schedulerを使用)。
  • 投機的セットはRMに転送されません。代わりに、ノードでローカルに実行されている`DistributedScheduler`によって処理されます。具体的には、`DistributedScheduler`は、クラスタ内で負荷の最も低いノードのリストを保持し、ラウンドロビン方式でコンテナを割り当てます。RMは、NM-RMハートビートを介して、定期的に`DistributedScheduler`に負荷の最も低いノードについて通知します。

上記の prosedur は、上記の集中型投機的スケジューリングの場合に`OpportunisticContainerAllocatorAMService`によって実行される prosedur と似ています。主な違いは、分散型の場合、要求の保証付きと投機的への分割がノードでローカルに行われ、保証付き要求のみがRMに転送され、投機的要求はRMに連絡することなく処理されることです。

割り当てノードの決定

各NMは、NM-RMハートビートを介して、実行中の保証付きコンテナと投機的コンテナの数、およびキューに入れられた投機的コンテナの数をRMに定期的に通知します。RMはすべてのノードからこの情報を収集し、負荷の最も低いノードを決定します。

投機的コンテナの集中型割り当ての場合、割り当てが集中して行われるため、この情報はすぐに利用できます。分散スケジューリングの場合、負荷の最も低いノードのリストは、RMからNMへのハートビート応答を介してすべてのNMに伝播されます(したがって、`DistributedSchedulers`で利用できるようになります)。NMに送信される負荷の最も低いノードの数は設定可能です。

現時点では、投機的コンテナがそのノードに送信された場合に待機する必要がある時間を推定し、したがって負荷の最も低いノードを決定するために、各ノードでキューに入れられた投機的コンテナの数のみを考慮しています。AMが推定タスク時間に関する情報を提供してくれた場合、キューの待機時間の推定値を向上させるために、それらを考慮に入れることができます。

ノード負荷の再調整

(古いキューの長さの推定値のため)投機的コンテナの配置の選択が不適切になる場合があり、ノード間の負荷の不均衡につながる可能性があります。問題は、クラスタの負荷が高い場合、および分散スケジューリングの場合(複数の`DistributedSchedulers`が互いに調整しないため、同じNMにコンテナを配置する可能性がある)に、より顕著になります。NMキュー間のこの負荷の不均衡に対処するために、負荷分散を実行して、NM間の負荷を動的に再調整します。具体的には、各NMによって公開されたキュー時間推定値をRMで集計する際に、分布を構築し、NMキューの長さの目標最大値を(分布の平均と標準偏差に基づいて)見つけます。次に、RMは、ハートビート応答を介してこの値をさまざまなNMに配布します。その後、この情報を使用して、キューの長さがしきい値を超えているノードのNMは、この最大値を満たすために投機的コンテナを破棄します。これにより、関連付けられた個々のAMは、それらのコンテナを他の場所に再スケジュールすることを強制されます。

高度な構成

機会的コンテナ割り当てを有効にし、集中型と分散型割り当てを選択するための主なプロパティについては、このドキュメントの冒頭のクイックガイドで説明しました。ここでは、より高度な構成について説明します。これらのパラメータには、ほとんどの場合、デフォルト値を使用すれば十分です。以下のすべてのパラメータは、conf/yarn-site.xmlファイルで定義する必要があります。

機会的コンテナのスケジューリング時に使用される負荷の低いノードの数と、このリストの更新頻度を決定するには、次のパラメータを使用します。

プロパティ 説明 デフォルト値
yarn.resourcemanager.opportunistic-container-allocation.nodes-used コンテナ割り当て中にコンテナをディスパッチするために、機会的コンテナアロケータが使用する負荷の低いノードの数。値を大きくすると、大規模クラスタの負荷分散を改善できます。 10
yarn.resourcemanager.nm-container-queuing.sorting-nodes-interval-ms 負荷の低いノードを計算する頻度。 1000

上記のノード負荷のリバランスセクションで説明したように、RMは一定の間隔で、すべてのNMキューの長さを収集し、それらの平均値(avg)と標準偏差(stdev)、および値avg + k*stdevkは浮動小数点数)を計算します。この値は、NM-RMハートビートを介してすべてのNMに伝播されます。NMは、現在のキューの長さがqueue_min_lengthqueue_max_lengthの値の間にある限り(これらの値は、非常に短いキューからのタスクのデキューを回避し、長いキューからのタスクを積極的にデキューするために使用されます)、その値を尊重してコンテナをデキューする必要があります(必要な場合)。パラメータkqueue_min_length、およびqueue_max_lengthは、次のように指定できます。

プロパティ 説明 デフォルト値
yarn.resourcemanager.nm-container-queuing.queue-limit-stdev kパラメータ。 1.0f
yarn.resourcemanager.nm-container-queuing.min-queue-length queue_min_lengthパラメータ。 5
yarn.resourcemanager.nm-container-queuing.max-queue-length queue_max_lengthパラメータ。 15

最後に、分散スケジューリングが使用される場合に、AMRMProxyServiceをさらに調整するための2つのプロパティがあります。

プロパティ 説明 デフォルト値
yarn.nodemanager.amrmproxy.address AMRMProxyServiceがバインドされるアドレス/ポート。 0.0.0.0:8049
yarn.nodemanager.amrmproxy.client.thread-count さまざまなジョブによってAMRMProxyServiceに登録されたインターセプターを提供するために、各NMで使用されるスレッドの数。 3

今後の課題

ここでは、機会的コンテナの割り当てと実行を拡張/強化できる複数の方法について説明します。また、各項目を追跡するJIRAも提供します。

  • リソースのオーバーコミットYARN-1011)。すでに説明したように、クラスタリソースの利用率をさらに向上させるために、割り当てられたリソースではなく、実際に利用されたリソースに基づいてコンテナをスケジュールできます。リソースをオーバーコミットする場合、実行中のコンテナの利用リソースが増加した場合にリソースが不足するリスクがあります。したがって、ノードの容量を超える割り当てのコンテナには、機会的実行を使用する必要があります。このようにして、リソースを再利用するために強制終了する機会的コンテナを選択できます。
  • NMキューの並べ替えYARN-5886)。キューに入れられたコンテナをFIFO順に実行する代わりに、次に実行される機会的コンテナを動的に決定する並べ替え戦略を採用できます。たとえば、実行時間が短いと予想されるコンテナや、完了に近いアプリケーションに属するコンテナを優先できます。
  • NMでの順序外れの強制終了YARN-5887)。上記で説明したように、保証されたコンテナが実行を開始するためにリソースを解放する必要がある場合、到着の逆順(最初に最も最近開始されたもの)で機会的コンテナを強制終了します。これは、常に正しい決定とは限りません。たとえば、強制終了されるコンテナの数を最小限に抑えたり、完了に非常に近いジョブのコンテナの強制終了を避けたりすることができます。
  • コンテナの一時停止YARN-5292):現時点では、リソースの競合が発生した場合に、保証されたコンテナのためにリソースを確保するために、機会的コンテナを強制終了します。ビジー状態のクラスタでは、これにより効果的なクラスタ使用率が低下する可能性があります。実行中の機会的コンテナを強制終了するたびに、再起動する必要があるため、作業が失われます。このため、実行中の機会的コンテナを一時停止することもできます。これは、コンテナエグゼキュータ(たとえば、使用されているコンテナテクノロジー)とアプリケーションからのサポートが必要になります。
  • コンテナのプロモーションYARN-5085)。実行中にコンテナの実行タイプを変更すると有利になる場合があります。たとえば、アプリケーションはコンテナを機会的として送信し、実行が開始されると、強制終了されないように保証されたコンテナへの昇格をリクエストできます。