Capacity Schedulerについて

この記事は、以下の記事の翻訳です。誤訳等ありましたら、編集リクエストをいただけると嬉しいです。

https://hadoop.apache.org/docs/r2.7.3/hadoop-yarn/hadoop-yarn-site/CapacityScheduler.html

# 目的

このドキュメントは、Hadoopのプラグイン可能なスケジューラであるの一つであるCapacitySchedulerについて説明します。CapacitySchedulerはマルチテナントのためにクラスタを安全に共有することを可能にし、その目的は割り当てられた容量の制約の下で、アプリケーションに適切にリソースが割り当てられるようにすることです。

# 概要

CapacitySchedulerは、クラスタのスループットと利用率を最大にしながら、Hadoopアプリケーションを共有のマルチテナントなクラスタとして、オペレータフレンドリーな方法で実行するように設計されています。

従来、各組織は、それぞれのSLAを満たすキャパシティを持つ独自のクラスタを持っていました。このやり方は、一般に、平均的な利用率の低下と、組織ごとにあるクラスタを管理することによるオーバーヘッドにつながります。組織間でクラスタを共有することは、それぞれでクラスタを作成・管理する必要がなく、規模の経済効果を得ることができるので、大規模なHadoopクラスタを運用する費用対効果の高い方法です。しかし、一つのクラスタを複数の組織で使用することは、他の組織とリソースを共有することになるので、SLAを満たす上で懸念があります。

CapacitySchedulerは、大規模なクラスタを共有しながら各組織のキャパシティを保証できるように設計されています。その中心的なアイデアは、Hadoopクラスタの利用可能なリソースが、コンピューティングの必要性に基づいてクラスタに共同で資金を出す複数の組織の中で共有されていることです。また、組織が他の人が使用していない余分なキャパシティにアクセスできるという特徴もあります。これは、費用効果の高い方法で組織に弾力性(elasticity)を提供します。

組織間でクラスタを共有するには、マルチテナントを強力にサポートする必要があります。それは、アプリケーションやユーザーが、共有クラスタを透過的に使用できることを保証するために、各組織にキャパシティとセーフティガードを保証する必要があるからです。CapacitySchedulerは、アプリケーション、ユーザーまたはキューがクラスタ内の過度な量のリソースを消費できないように、厳密な制限を設けています。また、CapacitySchedulerは、クラスタの公平性と安定性を確保するために、一人のユーザーとキューから初期化された/保留中のアプリケーションに制限を設けています。

CapacitySchedulerによって提供される主な抽象化はキューの概念です。 これらのキューは、通常、管理者が共有クラスタの経済性を反映するように設定します。

CapacitySchedulerは、リソースの共有に関するさらなるコントロールと予測可能性を提供するために、階層キューをサポートして、他のキューが空きリソースを使用する前に、リソースが下位のキュー間で共有されるようにします。それによって、組織内のアプリケーション間で空いているリソースを共有することの親和性を提供します。

# 機能

CapacitySchedulerは次の機能をサポートしています。

* `階層型キュー` - キューの階層は、他のキューが空きリソースを使用する前に、リソースが子キュー間で共有されるようにサポートされています。それによって、さらなるコントロールと予測可能性が備わっています。

* `キャパシティの保証` - キューはある一定の自由に使えるリソースのキャパシティとしてクラスタの一部が割り当てられます。キューにサブミットされたすべてのアプリケーションは、そのキューに割り当てられたリソースにアクセスできます。管理者は、各キューに割り当てられたリソースにソフトリミットとハードリミット(オプション)を設定できます。

* `セキュリティ` - 各キューには厳格なACLがあり、どのユーザーが個々のキューにアプリケーションをサブミットできるかを制御します。また、ユーザーが他のユーザーのアプリケーションを表示や変更できないようにするためのセーフガードがあります。また、キュー単位の設定やシステム管理者ロールもサポートされています。

* `弾力性` - 空きリソースは、キャパシティを超えるキューに割り当てられます。これらのリソースは、キャパシティ以下で実行されるキューから要求されると、そのキュー上のアプリケーションに割り当てられます（プリエンプションもサポートしています）。これにより、リソースを予測可能かつ柔軟に使用できるようになり、クラスタ内のリソースのサイロ化を防止することができます。

* `マルチテナント` - CapacitySchedulerは包括的な制限をサポートしているので、単一のアプリケーション、ユーザーおよびキューが、キューまたはクラスタ全体のリソースを独占してしまうことを防ぎます。

* `操作性`
  * 実行時に(再起動なしで)設定を変更可能 - キャパシティ、ACLなどのキューの定義とプロパティは、管理者が実行時に安全なやり方で変更することができるので、ユーザーの中断を最小限に抑えることができます。また、ユーザーと管理者がシステムのさまざまなキューへのリソースの現在の割り当てを表示するためのコンソールも用意されています。管理者は実行時に追加のキューを追加できますが、実行時にキューを削除することはできません。
  * アプリケーションの排出 -　管理者は、実行時にキューを停止することができます。この時、既に実行されているアプリケーションは完了するまで動き続けますが、新しいアプリケーションをサブミットすることはできません。キューがSTOPPED状態の場合、新しいアプリケーションをそのキューまたはその子キューにサブミットすることはできません。既存のアプリケーションは完了するまで動き続けるので、キューに既にサブミットされたアプリケーションは正常に排出されます。管理者は停止したキューを開始することもできます。

* `リソースベースのスケジューリング` - リソースを多く使用するアプリケーションをサポートしているので、アプリケーションでデフォルトより高いリソース要件を指定することで、複数のリソース要件が異なるアプリケーションを実行することが可能です。現在はメモリベースのスケジューリングをサポートしています。

* `ユーザーまたはグループに基づくキューマッピング` - この機能を使用すると、ユーザーまたはグループに基づいて特定のキューにジョブをマップできます。

# 設定

## ResourceManagerの設定

CapacitySchedulerを使用するようにResourceManagerを設定するには、`conf/yarn-site.xml`に次のプロパティを設定します。

|プロパティ|値|
|---|---|
|yarn.resourcemanager.scheduler.class| org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler|

## キューの設定

`etc/hadoop/capacity-scheduler.xml`は、CapacitySchedulerの設定ファイルです。CapacitySchedulerには、rootと呼ばれる定義済みのキューがあります。システム内のすべてのキューは、rootキューの子です。

さらにキューを設定するには、yarn.scheduler.capacity.root.queuesをコンマ区切りの子キューのリストで構成します。

CapacitySchedulerの設定では、キューパスという概念を使用してキューの階層を構成します。 キューのパスは、rootで始まるキューの階層のフルパスです。.(ドット)をデリミタとして使用します。

子キューは、yarn.scheduler.capacity.\<queue-path>.queuesのように設定できます。子キューは、特に明記しない限り、親から直接プロパティを継承しません。

下記は、3つのトップレベルの子キューa、b、cと、aとbがいくつかの子キューを持つ例です。

```
<property>
  <name>yarn.scheduler.capacity.root.queues</name>
  <value>a,b,c</value>
  <description>The queues at the this level (root is the root queue).
  </description>
</property>

<property>
  <name>yarn.scheduler.capacity.root.a.queues</name>
  <value>a1,a2</value>
  <description>The queues at the this level (root is the root queue).
  </description>
</property>

<property>
  <name>yarn.scheduler.capacity.root.b.queues</name>
  <value>b1,b2,b3</value>
  <description>The queues at the this level (root is the root queue).
  </description>
</property>
```

## キューのプロパティ

### リソース割り当て

|プロパティ|説明|
|---|---|
|yarn.scheduler.capacity.\<queue-path>.capacity|キューのキャパシティ(%)を浮動小数で設定(例：12.5)。すべてのキューの容量の合計は、各階層で100に等しくなければなりません。キュー内のアプリケーションは、空きリソースがあれば、キューの容量より多くのリソースを消費します。|
|yarn.scheduler.capacity.\<queue-path>.maximum-capacity|最大のキューのキャパシティ(%)を浮動小数で設定。空きリソースがあってもこれ以上は消費しない。デフォルトは-1で無効。|
|yarn.scheduler.capacity.\<queue-path>.minimum-user-limit-percent|各キューは、リソースの需要がある場合には、任意の時点でユーザーに割り当てられたリソースの割合に制限を適用します。ユーザーの制限は、最小値と最大値の間で変更できます。前者（最小値）はこのプロパティ値に設定され、後者（最大値）はアプリケーションを送信したユーザー数に依存します。たとえば、このプロパティの値が25であるとします。2人のユーザーがアプリケーションをキューにサブミットした場合、1人のユーザーはキューリソースの50％以上は使用できません。3人目のユーザーがアプリケーションを送信した場合、1人のユーザーはキューリソースの33％以上は使用できません。4人かそれ以上のユーザーでは、キューリソースの25％以上は使用できません。値が100の場合、ユーザー制限は課されません。デフォルトは100です。値は整数として指定されます。|
|yarn.scheduler.capacity.\<queue-path>.user-limit-factor|1人のユーザーがより多くのリソースを取得できるキャパシティの倍数。デフォルトでは、これは1に設定されています。この設定では、クラスタの空き状況に関係なく、1人のユーザーがキューのキャパシティを超えることはありません。 値は浮動小数点数として指定されます。|
|yarn.scheduler.capacity.\<queue-path>.maximum-allocation-mb|リソースマネージャで各コンテナ要求に割り当てるメモリのキューあたりの最大サイズ。この設定は、クラスタ全体の設定`yarn.scheduler.maximum-allocation-mb`を上書きします。 この値はクラスタ全体の設定値以下でなければなりません。|
|yarn.scheduler.capacity.\<queue-path>.maximum-allocation-vcores|リソースマネージャで各コンテナ要求に割り当てる仮想コアのキューごとの最大数。この設定は、クラスタ全体の設定`yarn.scheduler.maximum-allocation-vcores`を上書きします。この値はクラスタ全体の設定値以下でなければなりません。|

### 実行中および保留中のアプリケーションの制限

CapacitySchedulerは、実行中および保留中のアプリケーションを制御するために次のパラメータをサポートしています。

|プロパティ|説明|
|---|---|
|yarn.scheduler.capacity.maximum-applications / yarn.scheduler.capacity.\<queue-path>.maximum-applications|実行中と保留中の両方で同時にアクティブにできるアプリケーションの最大数。各キューの制限は、キューのキャパシティとユーザーの制限に正比例します。この設定はハードリミットであり、この制限に達するとサブミットされたアプリケーションは拒否されます。デフォルトは10000です。`yarn.scheduler.capacity.maximum-applications`ですべてのキューに対して設定でき、`queue.scheduler.capacity.<queue-path>.maximum-applications`を設定することで、キューごとにオーバーライドすることもできます。整数値で指定します。|
|yarn.scheduler.capacity.maximum-am-resource-percent / yarn.scheduler.capacity.\<queue-path>.maximum-am-resource-percent|アプリケーションマスターを実行するために使用できるクラスター内の最大リソース数 - 同時にアクティブなアプリケーションの数を制御します。各キューの制限は、キューのキャパシティとユーザーの制限に正比例します。浮動小数点数として指定されます。つまり、0.5 = 50％です。デフォルトは10％です。`yarn.scheduler.capacity.maximum-am-resource-percent`ですべてのキューに対して設定でき、`yarn.scheduler.capacity.<queue-path>.maximum-am-resource-percent`を設定することで、キューごとにオーバーライドすることもできます。|

### キューの管理とアクセス許可

CapacitySchedulerは、キューを管理するための次のパラメータをサポートしています。

|プロパティ|説明|
|---|---|
|yarn.scheduler.capacity.\<queue-path>.state|キューの状態。RUNNINGまたはSTOPPEDのいずれかになります。キューがSTOPPED状態の場合、新しいアプリケーションをそのキューまたはその子キューにサブミットすることはできません。したがって、rootキューがSTOPPEDの場合、クラスタ全体にアプリケーションをサブミットすることはできません。すでに実行中のアプリケーションは完了するまで実行されるので、キュー内のアプリケーションはは正常に排出されます。 値は列挙型(RUNNINGまたはSTOPPED)として指定されます。|
|yarn.scheduler.capacity.root.\<queue-path>.acl_submit_applications|特定のキューにアプリケーションをサブミットできるユーザーを制御するACL。あるユーザ/グループがキューまたは階層内の親キューに必要なACLを持っている場合、アプリケーションをサブミットすることができます。このプロパティが指定されていない場合は、親キューから継承されます。|
|yarn.scheduler.capacity.root.\<queue-path>.acl_administer_queue|特定のキュー上のアプリケーションの管理権限を持つユーザーを制御するACL。特定のユーザー/グループに、指定されたキューまたは階層内の親キューのいずれかに必要なACLがある場合は、アプリケーションを管理できます。このプロパティが指定されていない場合は親キューから継承されます。|

注：ACLは、user1、user2 group1、group2のような形式で指定します。\*を指定すると「誰でも」を意味します。逆にスペースを指定すると「誰でもない」を意味します。指定されていない場合のrootキューのデフォルト値は\*です。

### ユーザまたはグループに基づくキューマッピング

CapacitySchedulerは、ユーザーまたはグループに基づいてキューのマッピングを設定するために次のパラメータをサポートしています。

|プロパティ|説明|
|---|---|
|yarn.scheduler.capacity.queue-mappings|この設定では、ユーザーまたはグループの特定のキューへのマッピングを指定します。 単一のユーザーまたはユーザーの一覧をキューにマップできます。 シンタックスは、`[u or g]：[name]：[queue_name][,next_mapping]*`。ここで、uまたはgは、マッピングがユーザーまたはグループのマッピングかどうかを示します。値はユーザーの場合は`u`、グループの場合は`g`です。`name`はユーザー名またはグループ名を示します。アプリケーションをサブミットしたユーザーを指定するには、`％user`を使用します。`queue_name`は、アプリケーションをマップする必要があるキュー名を示します。ユーザ名と同じキュー名を指定するには、`％user`を使用できます。 ユーザーが属するプライマリグループの名前と同じキュー名を指定するには、`％primary_group`を使用できます。|
|yarn.scheduler.capacity.queue-mappings-override.enable|この機能は、ユーザーがキューマッピングを上書きできるかどうかを指定するために使用します。 これはブール値で、デフォルト値はfalseです。|

例

```
<property>
  <name>yarn.scheduler.capacity.queue-mappings</name>
  <value>u:user1:queue1,g:group1:queue2,u:%user:%user,u:user2:%primary_group</value>
  <description>
    Here, <user1> is mapped to <queue1>, <group1> is mapped to <queue2>, 
    maps users to queues with the same name as user, <user2> is mapped 
    to queue name same as <primary group> respectively. The mappings will be 
    evaluated from left to right, and the first valid mapping will be used.
  </description>
</property>
```

## コンテナのプリエンプション

CapacitySchedulerは、指定されたキャパシティ以上のリソースを使用しているキューからのコンテナのプリエンプションをサポートしています。アプリケーションコンテナのプリエンプションを有効にするために、yarn-site.xmlの以下のパラメーターを有効にする必要があります。

|プロパティ|説明|
|---|---|
|yarn.resourcemanager.scheduler.monitor.enable|yarn.resourcemanager.scheduler.monitor.policiesで指定される定期モニタを有効にします。デフォルト値はfalseです。|
|yarn.resourcemanager.scheduler.monitor.policies|SchedulingEditPolicyクラスのリストを指定します。設定されたポリシーはスケジューラと互換性がある(SchedulingEditPolicyインターフェースを実装している)必要があります。 デフォルト値は、CapacitySchedulerと互換性のあるorg.apache.hadoop.yarn.server.resourcemanager.monitor.capacity.ProportionalCapacityPreemptionPolicyです。|

yarn-site.xmlには、ProportionalCapacityPreemptionPolicyクラスが設定されている場合に、コンテナのプリエンプションを制御するために、次のパラメータを設定できます。

|プロパティ|説明|
|---|---|
|yarn.resourcemanager.monitor.capacity.preemption.observe_only|trueの場合、ポリシーを実行しますが、クラスタにプリエンプションや強制終了のイベントは影響しません。デフォルト値はfalseです。|
|yarn.resourcemanager.monitor.capacity.preemption.monitoring_interval|ProportionalCapacityPreemptionPolicyポリシーの呼び出し間隔（ミリ秒単位）。デフォルト値は3000。|
|yarn.resourcemanager.monitor.capacity.preemption.max_wait_before_kill|アプリケーションからのプリエンプションを要求してからコンテナを強制終了するまでの時間（ミリ秒）。 デフォルト値は15000です。|
|yarn.resourcemanager.monitor.capacity.preemption.total_preemption_per_round|1ラウンドでプリエンプションされるリソースの最大パーセンテージ。この値を設定することで、クラスタからコンテナを回収するペースを抑えることができます。必要なプリエンプションの総量を計算した後、この設定で指定された制限内に収まるように縮小します。デフォルト値は0.1です。|
|yarn.resourcemanager.monitor.capacity.preemption.max_ignored_over_capacity|Maximum amount of resources above the target capacity ignored for preemption. This defines a deadzone around the target capacity that helps prevent thrashing and oscillations around the computed target balance. High values would slow the time to capacity and (absent natural.completions) it might prevent convergence to guaranteed capacity. Default value is 0.1|
|yarn.resourcemanager.monitor.capacity.preemption.natural_termination_factor|Given a computed preemption target, account for containers naturally expiring and preempt only this percentage of the delta. This determines the rate of geometric convergence into the deadzone (MAX_IGNORED_OVER_CAPACITY). For example, a termination factor of 0.5 will reclaim almost 95% of resources within 5 * #WAIT_TIME_BEFORE_KILL, even absent natural termination. Default value is 0.2|

CapacitySchedulerは、キューに送信されたアプリケーションコンテナのプリエンプションを制御するために、capacity-scheduler.xmlで次の設定をサポートしています。

|プロパティ|説明|
|---|---|
|yarn.scheduler.capacity.\<queue-path>.disable_preemption|この構成をtrueに設定すると、特定のキューにサブミットされたアプリケーションコンテナのプリエンプションを無効にすることができます。 このプロパティは、yarn.resourcemanager.scheduler.monitor.enableをtrueに設定し、yarn.resourcemanager.scheduler.monitor.policiesをProportionalCapacityPreemptionPolicyに設定することで、システム全体のプリエンプションが有効になっている場合にのみ適用されます。このプロパティがキューに対して設定されていない場合、プロパティ値はキューの親から継承されます。デフォルト値はfalseです。|

## その他のプロパティ

### Resource Calculator

|プロパティ|説明|
|---|---|
|yarn.scheduler.capacity.resource-calculator|スケジューラー内のリソースを比較するために使用されるResourceCalculatorの実装クラスを指定する。デフォルトのorg.apache.hadoop.yarn.util.resource.DefaultResourCalculatorはメモリのみを使用し、DominantResourceCalculatorはメモリ、CPUなどの多次元リソースを比較するためにDominant-resourceを使用します。|

### データローカリティ

|プロパティ|説明|
|---|---|
|yarn.scheduler.capacity.node-locality-delay|CapacitySchedulerがラック・ローカルなコンテナをスケジュールしようとする試行数。通常、これはクラスタ内のノード数に設定する必要があります。デフォルトでは40に設定されています。正の整数値が必要です。|

## CapacitySchedulerの設定の確認

インストールと設定が完了したら、YARNクラスタを起動した後に、それらの設定をWeb UIからで確認できます。

* 通常の方法でYARNクラスタを起動します。
* ResourceManager Web UIを開きます。
* /schedulerのWebページには、個々のキューのリソース使用量が表示されます。

# キューの設定の変更

キューのプロパティを変更し、新しいキューを追加するのは非常に簡単です。`conf/capacity-scheduler.xml`を編集し、`yarn rmadmin -refreshQueues`を実行する必要があります。

```
$ vi $HADOOP_CONF_DIR/capacity-scheduler.xml
$ $HADOOP_YARN_HOME/bin/yarn rmadmin -refreshQueues
```

注：キューは削除できません。新しいキューの追加のみがサポートされています。また、更新されたキューの設定は有効なものである必要があります。つまり、各レベルのキューのキャパシティは合計100％にならないといけません。