CapacitySchedulerでのリソース管理

前のエントリでは各ノードのメモリ管理について書いたので、次にクラスタ全体のリソース管理として
CapacitySchedulerについてのメモです。
なお、CDH4.1.2で試した結果ですので、最新のバージョンとは(ry

CapacitySchedulerについて

クラスタ上では同時に様々なmapreduceを実行するのが普通だと思います。
CapacitySchedulerを利用すると、各jobごとに重要度に応じて、柔軟なリソース割り当てを行うことができます。

詳細は以下を確認してください。
http://archive.cloudera.com/cdh4/cdh/4/hadoop/hadoop-yarn/hadoop-yarn-site/CapacityScheduler.html


以下、微妙に気になったトコをメモしていきます。

rootのcapacity設定は必須

自明なのでなくてもいい気がしますが、無いと怒られます。

<property>
  <name>yarn.scheduler.capacity.root.capacity</name>
  <value>100</value>
</property>

defaultのcapacity設定は必須

defaultはjob設定でマッチするqueueがない場合に割り当てられるqueueです。
無いとやっぱり怒られます

<property>
  <name>yarn.scheduler.capacity.root.queues</name>
  <value>default</value>
</property>
<property>
  <name>yarn.scheduler.capacity.root.default.capacity</name>
  <value>100</value>
</property>

各キューのcapacityとmaximum-capacityとuser-limit-factorの関係

分かりにくかったのですが、、、

  • クラスタがアイドル状態の場合
    • そのjobは"capacity*user-limit-factor +α"分までリソースを利用できる。
    • ただしqueue全体でmaximum-capacityを超えることはできない。
  • クラスタがビジー状態の場合
    • "capacity+α"分までリソースを利用できる
    • 上記の"+α"分は弾力性設定で、capacityを少し超えるまではコンテナを起動できる。
    • そのためuser-limit-factorが1でも"Over Capacity"状態になりうる。

minimum-user-limit-percentの影響はよくわかりませんでした(汗

アドホックなHiveクエリ等の野良MapReduceはdefaultで、定期的なバッチ等はmanagedで実行することを想定しています。

<property>
  <name>yarn.scheduler.capacity.root.capacity</name>
  <value>100</value>
</property>
<property>
  <name>yarn.scheduler.capacity.root.queues</name>
  <value>default,managed</value>
</property>

<property>
  <name>yarn.scheduler.capacity.root.default.capacity</name>
  <value>40</value>
</property>
<property>
  <name>yarn.scheduler.capacity.root.default.user-limit-factor</name>
  <value>1.5</value>
</property>
<property>
  <name>yarn.scheduler.capacity.root.default.maximum-capacity</name>
  <value>70</value>
</property>

<property>
  <name>yarn.scheduler.capacity.root.managed.capacity</name>
  <value>60</value>
</property>
<property>
  <name>yarn.scheduler.capacity.root.managed.user-limit-factor</name>
  <value>2</value>
</property>

この場合ですが、

  • アイドル状態のときは
    • defaultに投入されたジョブは60%(= 40% * 1.5)までリソースを使用可
    • defaultに複数ジョブが投入された場合、合計で最大70%までリソースを使用可
    • managedに投入されたjobは100%のリソースを利用可
  • 非アイドル状態のときは
    • defaultに投入されたジョブは40%までリソースを使用可
    • managedに投入されたジョブは60%までリソースを使用可
  • defaultが70%リソースを使用しているときにmanagedにジョブが突っ込まれたら
    • managedはとりあえず30%のリソースでジョブが実行できる。
    • defaultに投入されたジョブのコンテナが終了すると、managed側が空いたリソースでコンテナを起動できる。

まとめ

以下のような考え方で各queueの設定を決めていけばいいと思います。

  • capacityはクラスタがビジーのときにどれくらいの割合でリソースを割り振りたいかで決定する。
  • maximum-capacityは、他queueのために最低限どれくらいリソースを残しておきたいかで決定する。
  • user-limit-factorは、アイドル状態で効く設定なので気持ち多めでいいんじゃないかと。

なおqueueはツリー的に細分化して設定していくこともできます。
上の例では面倒なので、defaultとそれ以外みたいなカンジにしてしまってますが。