あの日見たYARNのお仕事を僕達はまだ知らない。

あなたが実行したジョブのこと考えてない間、ずっとYARNがジョブのこと考えててくれてたんだ
===
みなさんはYARNの存在をどれだけ気づいてあげられているだろうか。

> * よくSparkと一緒にYARNって単語はよくみるよねー
> * 知ってる知ってる、よく図とかでMapReduceとかの下にいるやつだよね？
> * クラスタのリソースを管理してるんでしょ、たしか？

いや、間違ってはいないし、やっていることをあたっているんだけど、実はいつも頑張ってくれているYARNのことをもっと理解してあげてもいいじゃないか!

ただ、

>* いざ調べてみると日本語の情報が少ない
>* なんかざっくりリソース管理を行うぐらいしか書いてない
>* もしくはいきなり細かい話から始まってよくわからない

というのがちまたの現状なので、聖なる夜に暇を持て余した私が、いつも頑張ってるYARNのお仕事を紹介しようと思います。

YARNの素晴らしさを熱く語りたいところなのですが、そのせいにかえってYARNとの距離を感じられてしまうと本末転倒です。
なので今回はYARNのお仕事の概要をわかりやすくお伝えできることを目標としてまとめてみました。


ありがとう、YARN
===
YARNは"Yet-Another-Resource-Negotiator"の略称で、汎用的なクラスタリソース管理フレームワークです。

YARNは従来からあるようなMapReduceといったバッチ処理、はたまたストリーミングのようなオンメモリでの処理をメインとしたような処理など、様々なワークロードに応じた分散アプリケーションをHadoopクラスタ(HDFS)上で動作させることができます。


わたしたち3人でYARNなんだものね
===
YARNを構成する主要要素と主な役割はこんな感じです。

* ResourceManager
  * クラスター全体のリソース管理を行う司令塔
  * 常駐プロセス
* NodeManager
  * 実際にアプリケーションを実行するワーカー
  * 常駐プロセス
* ApplicationMaster
  * 上の二つを仲介する存在
  * クラスタ上で実行されるアプリケーション毎に起動するプロセス

これらの関係をざくっと表すとこんな感じです。

![qiita1.png](https://qiita-image-store.s3.amazonaws.com/0/48330/cf32a897-ed1a-a7c5-85c0-18c1d53b3903.png)


YARNではクラスターのリソースをコンテナという単位で管理します。
コンテナの中には割り当てるメモリ量、CPUコア数といった情報が含まれています。
実際にアプリケーションがクラスタ上で実行される場合、必要なリソース量分のコンテナが割り当てられることで処理が実行されます。
下記がコンテナのイメージです。

![qiita2.png](https://qiita-image-store.s3.amazonaws.com/0/48330/fa3e06d7-0d6b-f6a0-cc8f-e71cbde50658.png)


コンテナの存在をふまえて、さっきの図をもうちょっと正確に書くとこんな感じになります。

![qiita3.png](https://qiita-image-store.s3.amazonaws.com/0/48330/b9fd65fa-5dd7-2dc3-9ddf-b2906d317f61.png)



そうなんすよ。かっけぇーんすよ、YARNは。
===
YARN上でアプリケーションが実行されて処理が完了するまでの流れをもうちょっと詳しく追ってみます。
以下のようなステップで処理が進んでいきます。(ざっくりしすぎすいません)

1. お願いYARN、アプリケーションを実行して!
2. 立ち上がれ!ApplicationMaster!
3. リソースください!
4. いざ、アプリケーション実行!ホウレンソウも大事だよ!
5. フィナーレ、アプリケーション終了

実行されるアプリケーションはMapReduceジョブでもいいですし、Sparkアプリケーションでも基本動作は同じです。


1. お願いYARN、アプリケーションを実行して!
---

さて、早速クラスタ上でアプリケーションを実行してみます。
いつも何気なく投入していたアプリケーションをクラスタ上で実行した際に、YARNが何をしているのかをみてみます。

1. まずアプリケーションを実行したいクライアントはResourceManagerから、そのクラスター上でアプリケーションを実行してもよいかの認証認可を受けます。
1. 認証認可が問題なければ、ResourceManagerから実行しようとしているアプリケーションを識別・管理するための一意なアプリケーションIDがクライアントに対して発行されます。
1. クライアントはResourceManagerから発行されたアプリケーションIDとともにアプリケーションの実行依頼を出します。

![qiita4.png](https://qiita-image-store.s3.amazonaws.com/0/48330/bf040e2b-a846-f2ed-6452-349dd0fa809f.png)



2. 立ち上がれ!ApplicationMaster!
---

無事クライアントはクラスタ上でアプリケーションの実行ができることになりました。
ただし、まだアプリケーション実行までにはやることがあります。
ResourceManager、NodeManagerは常に常駐しているプロセスなのですが、仲介役のApplicationMasterは実行されるアプリケーション毎に都度立ち上がるのでしたね。
次にやることは、アプリケーションを実行するために必要な登場人物を全員そろえることです。

1. ResourceManagerは、ApplicationMasterを起動させるためのノードをNodeManagerが稼動するノードから選択します。
1. 選ばれたノードに対して、ApplicationMasterを起動させるために必要なリソース分のコンテナを割り当てます。
1. ResourceManagerから割り当てられたコンテナをもとに選ばれたノードはApplicationMasterのプロセスを起動させます。

![qiita5.png](https://qiita-image-store.s3.amazonaws.com/0/48330/b5b45213-a719-dabf-27db-6e16f8497714.png)


3. リソースください!
---

今回実行するアプリケーション専任のApplicationMasterも無事起動し、やっとみんながそろいました。
アプリケーション実行まであと一歩です。
次にやることは、アプリケーション実行に必要なリソースをResourceManagerにおねだりすることです。
ただその前に、新米ApplicationMasterは無事起動できたことも含めてResourceManagerにご挨拶が必要です。

1. ApplicationMasterはResourceManagerに対して、改めて自分はここにいるよーと伝えて自分の情報を登録してもらいます。その際に、実行するアプリケーション情報をトレースするためのURL情報も一緒にResourceManagerに伝えます。
1. 1．の情報を受け取ったResourceManagerは、ちゃんと受け取ったよのお返事をApplicationMasterに返してあげます。
1. 無事受け入れてもらえたApplicationMasterは、次に実行するアプリケーションに必要なリソース分のコンテナをResourceManagerにおねだりします。
1. おねだりを受けたResourceManagerは、それ応じてコンテナをApplicationMasterに対して割り当ててあげます。

![qiita6.png](https://qiita-image-store.s3.amazonaws.com/0/48330/ca0bb0bc-9e5d-1825-6dcd-a749245da8ac.png)


4. いざ、アプリケーション実行!ホウレンソウも大事だよ!
---

必要なリソースも割り当てられて、いよいよアプリケーション実行の時です！
いよいよNodeManagerの本格的な出番の時です。
そして人間界のお仕事と一緒で、処理が始まったらちゃんとホウレンソウをしなくちゃいけません。

1. ApplicationMasterは割り当ててもらったコンテナを、今度はNodeManagerが稼動するノードに対して割り当てます。
1. リソースを割り当てられたNodeManagerたちはせっせと頑張ってアプリケーションを実行します。
1. 処理中もApplicationMasterは、NodeManagerに実行中のアプリケーションの処理状況を確認し、NodeManagerはそれに応じて状況を逐次伝えます。
1. 一方で、ResourceManagerもApplicationMasterが元気にやっているのかを確認し、ApplicationMasterから追加のコンテナ要求がきたらそれに応じたりしています。

![qiita7.png](https://qiita-image-store.s3.amazonaws.com/0/48330/51baf56d-d0b5-1a4a-3158-2d05d815e852.png)


5. フィナーレ、アプリケーション終了
---

そしてアプリケーションが無事完了しました。
ApplicationMasterのお仕事もこれにて終了で、さよならの時です。

1. アプリケーション処理が完了すると、ApplicationMasterはResourceManagerに対して、アプリケーションの実行結果と一緒に、自分のお仕事は終わったよーと伝えます。
1. そして役目を終えたApplicationMasterはもらったコンテナを開放し、自身のプロセスを終了します。(お疲れさま！)
1. 実行結果を受け取ったResourceManagerは、クライアントにその結果を伝えます。これにてアプリケーション実行は無事完了です! 

![qiita8.png](https://qiita-image-store.s3.amazonaws.com/0/48330/aab21251-7fb7-d53b-7255-629a2cec3017.png)


願い、叶えてくれてありがとな。大好きだ、YARN
====
何気なく実行していたジョブの裏で、実はこんなにYARNが頑張ってくれていたんですね。
これからジョブを実行する時は、「YARN、みーつけた!」って感じで存在に気づいてあげてください。