Skip to content

Instantly share code, notes, and snippets.

@tsuda7
Last active September 8, 2016 10:41
Show Gist options
  • Save tsuda7/3d25975f406f5af90fac44977f735fe4 to your computer and use it in GitHub Desktop.
Save tsuda7/3d25975f406f5af90fac44977f735fe4 to your computer and use it in GitHub Desktop.

Chapter4 YARN

YARN (Yet Another Resource Negotiator) は Hadoop クラスタクラスタのリソース管理システムであり、Hadoop2 から MapReduce の実装を改善するために導入されたが、他の分散システムにおいても利用できる。

YARN は API を提供しているが、ユーザーが直接利用するものではなく、YARN の上に分散処理システムが構築される(図を参照)。

Anatomy of a YARN Application Run

YARN は 2つのデーモンを利用する:

  • a resource manager (one per cluster)
    • クラスタ間のリソース調整を行う
  • node managers (running on all the nodes in the cluster)
    • to launch and monitor containers

コンテナは、アプリケーションプロセスを、制限されたリソース(メモリ、CPU など)上で実行するもの

(図参照, P.80)

  • To run an application on YARN, a client contacts the resource manager and asks it to run an application master process (step 1 in Figure 4-2).
  • The resource manager then finds a node manager that can launch the application master in a container (steps 2a and 2b).1
  • Precisely what the application master does once it is running depends on the application. It could simply run a computation in the container it is running in and return the result to the client. Or it could request more containers from the resource managers (step 3), and use them to run a distributed computation (steps 4a and 4b)
  • The latter is what the MapReduce YARN application does, which we’ll look at in more detail in “Anatomy of a MapReduce Job Run” on page 185.

Resource Requests

メモリ、CPU の他に locality(局所性)が制約として利用出来る(データが特定のノードやラック上に存在しているか、もしくは locality を設定しない(off-rack)が設定できる)

Locality を実現するためのノードに、すでに他の container が動いている場合などは、ラック上で探し、それでもだめならクラスタ内のノードでコンテナを起動させる…といったように、制約をゆるめていく。

MapReduce などの HDFS ブロックを利用する場合は、レプリカが存在するノード、レプリカが存在するラックという具合になる。

リソースの要求はアプリケーションの任意の時点で要求できるため、MapReduce では Mapper は最初に要求し、Reducer は必要になったタイミングで要求する(Spark ははじめに全て取得する)

Application Lifespan

YARN アプリケーションの lifespan は様々なので、カテゴライズする場合には "how they map to the jobs that users run" という観点から見ていく

  • Simplest
    • One application per user job (like Map Reduce)
  • The second model:
    • One application per workflow or user session of (possibly unrelated) jobs (like Spark)
    • コンテナが再利用できたり、中間データをジョブ間でキャッシュすることが出来る可能性があるため、効率的
  • The third model:
    • long-running application that is shared by different users.
    • Apache Slider などの coordination としての振る舞いをするときに

Building YARN Applications

YARN 上のアプリケーションを直接構築することは可能だが、多くの場合は既存のフレームワークを経由して使うのが良い。(例:Directed Acyclic graph (DAG) を実行する場合は Spark や Tez が適切だろうし、ストリーミングを扱う場合には Spark, Samza, Storm などが良いだろう。)

YARN 上でアプリケーションを動作させるのを容易にするプロジェクトもある(Apache Slider, Apache Twill)

YARN Compared to MapReduce 1

MapReduce 1 (Hadoop < 2) では, jobtracker と tasktracker があり、以下のような役割を果たしていた:

MapReduce 1 には 2つのデーモン:jobtracker と tasktracker(s) がある。jobtracker はタスクトラッカー上で動くタスクを調整する役割、Tasktrackers はタスクを実行し、結果を jobtracker へ伝える。タスクが失敗した場合は、jobtracker は別の tasktracker にタスクを割り当てる。

In MapReduce 1 では jobtracker は以下の2つを調整していた:

  • job scheduling (matching tasks with tasktrackers)
  • task progress monitoring (keeping track of tasks, restarting failed or slow tasks, and doing task bookkeeping, such as maintaining counter totals) の両方を調整していた。

一方で、MapReduce 2(in YARN) ではこれらは resource managerapplication master (one for each MapReduce job) に分離される。

MapReduce 1 YARN
Jobtracker Resource manager, application master, timeline server
Tasktracker Node manager
Slot Container

YARN を使う利点:

  • Scalability
    • 従来は Jobtracker がジョブ、タスクどちらも管理していたが、Resource manager と application master に分離されたことにより、スケーラビリティが向上している(4,000 nodes and 40,000 tasks -> 10,000 nodes and 100,000 tasks)
  • Availability
    • Resource manager, application master に分けたことにより、それぞれで HA を達成できている(詳しくは P.193)
  • Utilization
    • 従来は Map slot, Reduce slot に分かれており、Map slot しか余っていない場合は Reduce slot は待たなければいけなかった。YARN ではリソースプールとして全体を管理するため、このようなことは
  • Multitenancy
    • YARN 上で複数の分散アプリケーションを動かすことができる(MapReduce1, 2 を同時に動かすこともできる)

Scheduling in YARN

YARN ではスケジューリングポリシーを設定することができ、それぞれ紹介する。

Scheduler Options

3 schedulers are available in YARN. 詳しくは図 4-3。

A) FIFO

FIFO でアプリケーションにリソースを割り当てていく。リソースが足りなければ待機。

Shared cluster では Capacity Scheduler か Fair Scheduler を利用したほうが良い。そうすれば、長時間実行されるジョブも、アドホッククエリなど小さいジョブも適切な時間内に処理できる。

B) Capacity Scheduler

キューを分けてしまう方法。FIFO と比べて、小さいジョブがすぐに実行されている。しかしクラスタ全体のリソースを各キューが常時確保するため、FIFO と比べてもジョブの実行には時間がかかる。

C) Fair Schedulers

リソースを動的に割り当てる方法。job 2がきたタイミングで、job 1 に割り当てているものを解放し、job 2に割り当てる。(解放するための時間があるため、job 2 の実行開始にはラグが生じる)

 

Capacity, Fair Schedulers のさらなる設定について説明を続ける:

B) Capacity Scheduler Configuration

組織ごとなどでキューをもち、それぞれに決まったリソースを割り当てる。キューごとに FIFO でリソースを割り当てていく。

キューに複数のジョブが登録されていて、リソースが余っている場合は、複数のジョブにリソースを割り当てる。その際に yarn.scheduler.capacity.<queue-path>.user-limit-factor が 1を超えている場合は、キューのリソース上限を超えて割り当てる(queue elasticity)

Example 4-1 の例:

    root
    ├── prod
    └── dev
        ├── eng
        └── science
<?xml version="1.0"?>
<configuration>
  <property>
    <name>yarn.scheduler.capacity.root.queues</name>
    <value>prod,dev</value>
  </property>
  <property>
    <name>yarn.scheduler.capacity.root.dev.queues</name>
    <value>eng,science</value>
  </property>
  <property>
    <name>yarn.scheduler.capacity.root.prod.capacity</name>
    <value>40</value>
  </property>
  <property>
    <name>yarn.scheduler.capacity.root.dev.capacity</name>
    <value>60</value>
  </property>
  <property>
    <name>yarn.scheduler.capacity.root.dev.maximum-capacity</name>
    <value>75</value>
  </property>
  <property>
    <name>yarn.scheduler.capacity.root.dev.eng.capacity</name>
    <value>50</value>
  </property>
  <property>
    <name>yarn.scheduler.capacity.root.dev.science.capacity</name>
    <value>50</value>
  </property>
</configuration>
  • prod, dev で、dev がさらに2つのキューを持つ
  • prod, dev のリソース比は 40%, 60%
  • dev は必要に応じて全体の 75% まで利用可能(つまりprd はいつも25%は保証されている)
  • prd は必要におじてすべてのリソースを利用可能(dev はリソース容量は保証されていない)
  • eng, science は dev をさらに 50%, 50% で共有する

そのほかにも、1人のユーザーやアプリケーションが使えるリソースの制限や、アプリケーションの同時実行数の制御などが可能。

Queue placement

キュー名が与えられない場合は default キューを利用し、存在しないキュー名が与えられた場合は default ではなくエラーとして扱う。

C) Fair Scheduler Configuration

図 4-3 で見たのは1つのキューに対してだったが、複数のキューに対して調整もできる(図 4-4)

Enabling the Fair Scheduler

スケジューラは yarn.resourcemanager.scheduler.class で決まる。デフォルトは Capacity Scheduler だが、CDH だと Fair Scheduler がデフォルト。

Queue configuration

(Example 4-2 の説明)

<?xml version="1.0"?>
<allocations>
  <defaultQueueSchedulingPolicy>fair</defaultQueueSchedulingPolicy>

  <queue name="prod">
    <weight>40</weight>
    <schedulingPolicy>fifo</schedulingPolicy>
  </queue>

  <queue name="dev">
    <weight>60</weight>
    <queue name="eng" />
    <queue name="science" />
  </queue>

  <queuePlacementPolicy>
    <rule name="specified" create="false" />
    <rule name="primaryGroup" create="false" />
    <rule name="default" queue="dev.eng" />
  </queuePlacementPolicy>
</allocations>

  • <queue> はネスト可能
  • weight を省略した場合は同じ比で割り振る(eng, science は 1:1)
  • 各キューは異なるスケジューリングポリシーを持てる
    • fair
    • fifo
    • drf(後述, Dominant Resource Fairness)

Queue placement

どのキューを使うかはルールベースに決まる。

  • specified
  • primaryGroup
    • ユーザーの primary unix group を利用(なければ作成せずに次に)
  • default

<queuePlacementPolicy> が設定されない場合は、以下の内容が設定されたかのような挙動になる(指定したキューがあればそれを利用し、なければユーザー名のキューを利用(なければ作成する):

<queuePlacementPolicy>
  <rule name="specified" />
  <rule name="user" />
</queuePlacementPolicy>

デフォルトキューだけにも設定でき、その場合は yarn.scheduler.fair.user-as-default-queue を false にする(ユーザー個別のキューを作成しない)。

Preemption

Fair Scheduler は preemption(割り込み・先取り)が可能。

Preemption はスケジューラが、"fair share" を超えている分のコンテナを kill することを許可する。kill されたコンテナは再実行される必要があるため、クラスタ全体の効率は落ちる。

yarn.scheduler.fair.preemption を true にすると Preemption が設定される。これに関係したタイムアウト設定が2つあり、デフォルトでは設定されていないので少なくともどちらかは設定する必要がある:

  • one for minimum share (sec)
    • "minimum guaranteed share" が確保されずに、この時間設定が経過すると、スケジューラはほかのキューのコンテナを kill できる
  • one for fair share (sec)
    • half of "fair share" が確保されずにこの時間設定が経過すると、スケジューラはほかのキューのコンテナを kill できる

Delay Scheduling

忙しいクラスタでは局所性を確保するのが難しいが、実際にはすぐに条件を緩和せずに、最大数秒程度待つことで局所性を飛躍的に向上させることができる。この機能は Delay Scheduling と呼ばれ、Capacity / Fair Scheduler で利用可能。

Dominant Resource Fairness

"resource" がメモリだけ扱うなど、1つのタイプのみからなる場合は計算は簡単だが、複数のタイプを扱う場合には計算が複雑になる。これを扱う方法に DRF がある。

Imagine a cluster with a total of 100 CPUs and 10 TB of memory.

  • Application A requests containers of (2 CPUs, 300 GB)
    • (2%, 3%) -> dominant is 3%
  • Application B requests containers of (6 CPUs, 100 GB)
    • (6%, 1%) -> dominant is 6%
  • B は A の半分のコンテナが割り当てられる(2倍ではない)

デフォルトでは DRF はオフになっており、メモリのみチェックしている。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment