YARN キュー の基本：3つの種類（FIFO, Capacity, Fair）をメリデメとともに図解

# この記事について

YARN のキューには大きく分けて3つの種類があり、JOBの性質や優先度に応じて適切に設定する必要があります。

そのための第一歩として、この記事では、YARNという言葉を今初めて聞いた人でもYARNキューの3つの種類（FIFO, Capacity, Fair）について理解できるようにまとめてみました。

[いわゆる「象本」第4版](https://www.oreilly.com/library/view/hadoop-the-definitive/9781491901687/) の Scheduling in YARN セクションの内容をベースに、図に色をつけて補足したり、文章だけで説明されていることを絵にしたりしたものです。

この記事を読んで、まずは YARN のキューの概要把握に役立てていただければ幸いです。

# YARN キューの種類

YARNのキューには、FIFO スケジューラー, Capacity スケジューラー, Fair スケジューラー の３つの種類があります。

それぞれのキューの処理イメージを以下に図解しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/f59f84f6-d527-f6c6-7a21-e747ff495c23.png)

以下、それぞれのスケジューラーについて説明します。

## FIFO スケジューラー

名前のとおり先入れ先出し。
JOB1 の処理が終わってから JOB2 の処理を始めます。

### FIFOのメリット

FIFO はとにかく先に来たものからやっつけていくというシンプルさがメリットです。
シンプルゆえにオーバーヘッドも少なくてすみます。

また、先ほどの例でJOB1が終わるタイミングに注目すると、FIFOが一番早いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/e5cc1778-6113-7038-311a-911adbc74636.png)

### FIFOのデメリット

FIFOのデメリットは、優先度の考慮ができない点です。
たとえば先ほどの例で、先に到着した処理量の多いJOB1は優先度が低く、JOB2は優先度が高かったとします。

FIFOの場合、JOB2は優先度が高いにも関わらず、先に来た優先度の低いJOB1が終わるまで待っていなくてはなりません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/88060b10-f19c-4707-faa5-ca091fbc2bab.png)

実際の運用を考えると、この状況を許容できるケースは少なく、本番の運用でFIFOを使っているケースはそんなに多くないはずです。

## Capacity スケジューラー

Capacity スケジューラーは、キューをグループに分けてあらかじめ割り当て（＝Capacity）を決めておき、**原則として** その範囲内で処理をします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/75bf44c4-b63a-3321-adaf-8304e6648f0f.png)

### Capacity スケジューラーのメリット

Capacity スケジューラーのメリットは、あらかじめキューのキャパシティを決めているため、優先度の高いJOBがあとから来た場合に **原則として** すぐにJOBを開始できることです。

最初の図で比べてみると、JOB2が始まるタイミングは Capacity スケジューラーが一番早いことがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/5b2fc067-5f41-c75a-fb59-157f6b56e385.png)

JOB2が優先度の高い処理だった場合、これを早く開始できるのは大きなメリットです。

### Capacity スケジューラーのデメリット

Capacity スケジューラーのデメリットは、大きく分けて２つあります。

1. 空いているキャパシティが無駄になる
1. 割り当てられたキューの容量を必ずしもすぐに使えないケースがある

順番に見ていきましょう。

#### 1. 空いているキャパシティが無駄になる

これはわかりやすいと思います。

キャパシティスケジューラーの **原則** は、常に一定の割合を各キューに割り当てることです。
本番用を60%、開発用を40%と決めた場合、**原則として**、本番用は常に60%、開発用は常に40%の範囲でしか資源を使えません。

つまり開発用に割り当てられた40%の資源を全く使っていなくても、**原則として**、本番用は自分の割り当てである60%を超えて資源を使うことができません。
逆もしかりです。
これは無駄だよね、という話です。

図にするとこんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/b77f9123-b9df-67e3-9094-8bb662805347.png)

この問題により、最初の図で処理全体が終わるタイミングを比べると、Capacity スケジューラーが一番遅いことになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/84731bd5-f64f-bc2b-ef6f-f7f958bad30b.png)

:::note warn
ここでは単純化して説明していますが、3つのキューを比べた場合、処理全体が終わるのは常にCapacityスケジューラーが一番遅いとは限りません。
設定方法や、どういう組み合わせでJOBが発生するか、競合がどの程度起きるかなどの条件によっては、Fairスケジューラーの方が全体の処理時間がかかる場合もあります。
:::

#### 2. 割り当てられたキューの容量を必ずしもすぐに使えないケースがある

こちらはデメリットというよりは、注意点かもしれません。

Capacity キューの説明に関しては、この記事の中で何度も **原則として** という言葉を使っていますが、その **原則** が設定によっては当てはまらないケースがあります。

実は先述の「空いているキャパシティが無駄になる」という問題への対応として、Capacity スケジューラーを使っていても、 **設定によっては別のキューが空いている場合に、デフォルトの割り当てを超えた資源を使うことができます。**

ただし、このような設定を行った場合、後述する Fair スケジューラーと同様の問題点が発生し得ることになります。

これ以外にも、設定項目によってどういう振る舞いをするのかを理解して使っておかないと、「期待していたはずのキャパシティを取得できない」といったことが起こりえます。

:::note warn
Capacity スケジューラーによくある誤解とその対応を詳述した記事が色々と出ているのは、おそらくこの問題にハマる人が多いからだと思われます
:::

スケジューラーによくある誤解とその対応を詳述した記事は、英語だと色々と出ているのですが、日本語でわかりやすくまとめた記事が見当たらなかったため、後日記事を書きたいと思います。

## Fair スケジューラー

Fair スケジューラーでは、あらかじめ各キューに「フェアな割り当て」を決めておきます。
この点は Capacity スケジューラーと似ていますが、「他にJOBがない間は、そのJOBが資源を独占してOK」という点が異なります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/133944ce-8e83-d0ca-95d5-f22e29c95189.png)

上記の図は、「フェアな割り当て」がそれぞれ１：１（50%ずつ）っぽいイメージになっていますが、任意の割合を指定することが可能です。

### Fair スケジューラーのメリット

Fair スケジューラーのメリットは、優先度の高いJOBの割り込みを許しつつ、資源を効率よく使えることです。
先ほどの図でいえば、あとから割り込んできたJOB2を早く終わらせつつ、処理全体もFIFOの次に早く終わらせることができています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/4ad8112f-4a33-662d-d91e-737dc6cb7598.png)

:::note warn
単純化して説明していますが、実際には割り込みのJOBが終わるタイミングが Fair スケジューラーと Capacity スケジューラのどちらが速いかは、それぞれの設定やJOBの性質、組み合わせによって変わります。
処理全体が終わるタイミングについても同様です。
:::

### Fair スケジューラーのデメリット

Fair スケジューラーの注意点は、JOBの処理中はキューが常にフルで使われることになるため、割り込みのJOBが資源の割り当てをもらえるまで一定の待ち時間が発生することです。

たとえばJOB1が資源をフルで使っている状態でJOB2が実行されると、JOB2は自分の割り当てをもらえるまでに少し待つ必要があります。

これにより、もしも Capacityスケジューラーで常に一定の割合を空けておけばすぐに開始できたはずのJOBが、Fairスケジューラーの場合は一定時間待たないと開始できない、ということが起こり得ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/78c10063-8458-5634-7b66-6caa90185f49.png)

:::note warn
（Capacity スケジューラーのところでも書きましたが、）
この問題は実は Fair スケジューラーだけではなく、Capacityスケジューラーで自分の割り当てを超えた資源の利用を許可する設定にしていた場合も同様に起こり得ます。
:::

# まとめ

少し細かい注意事項をはさみながらになりましたが、YARNキューの基本編は以上です。
細かい注意事項に関する詳細記事は随時公開し、公開次第この記事からもリンクしたいと思います。

# 参考

象本第4版

https://www.oreilly.com/library/view/hadoop-the-definitive/9781491901687/