Resource Manager HA の概要と動かし方

本文章には，2013年時点での内容が含まれています．2017年04月13日に typo の修正を行いましたが，内容に関しては更新を行っていませんのでご注意ください．

この記事は，Hadoop Advent Calendar 2013 の 11日目の記事です．記事を書いている今現在，私は GMT で活動していますので，時間的にはセーフだと思います．また、TPO によらずHiveはかわいいです.

## 背景

### YARN とは

YARN は，Yet Another Resource Negotiator の略で， Hadoop v1 の JobTracker が行っていたリソース管理部分を MapReduce 以外にも利用しようと試みたものです．JobTracker は Map Slot/Reduce Slot という単位でリソース管理を行っていましたが，これをコンテナというより汎用的な単位でリソースを管理するように変更しました．これにより，Map Slot/Reduce Slot よりも細かく，効率良くリソースを利用することができるようになりました．

### Mesos との差異

できることはほぼ同じです．バックエンドも両方とも Linux Container です．しかし，設計哲学が異なるので，そこが現在の実装の差になって現れているように思います．例えば Mesos 上のアプリケーションは計算モデル(MapReduce/BSP etc.)ごとにマスターを立てる必要がありますが，YARN 上のアプリケーションは，ジョブごとにマスターを立ち上げる必要があります．このことにより，以下のような効果が見込めます:

* Mesos はジョブの立ち上げ時間が YARN と比較して短くなり得る．
* 計算機モデルごとのスケーラビリティは YARN の方が高くなり得る．

個人的には，このような現時点での些細な機能の差よりも，Hadoop のコミュニティがバックについているのが大きいと考えています．YARN/Mesos のコミュニティ共に開発は活発ですが，Mesos では MapReduce v2 (YARN 上で動作する MapReduce．様々な最適化が追加されている．)対応が未だ行われていません．

多くのユーザは MapReduce + αで何かを動かしたいと考えていることが多いため，Hadoop コミュニティと密に開発を行っている YARN の方がユースケースに合うのではないかなというのが現在の私の考えです．例えば，Spark/Imapala 辺りは，MapReduce を全て置き換えるものではなく，補完的な位置づけに止まっていますが，これらを YARN 上で動作させることにより HDFS/S3 上に入っているデータに対する解析をより高速に行うことができます．

現に，Cloudera の llama は YARN の弱点である起動時間の短縮のため，マスタとリソースをプールしておき，リクエスト時には llama がその中からリソースを割り当てるというアーキテクチャをとっています．このアプローチ自体には色々な課題がありますが，Cloudera にも YARN の開発者が居ますので，YARN のコミュニティと改善してくような動きになりそうです．

### 課題

YARN の課題として，Resource Manager が単一障害点であることが挙げられます(Hadoop v1 では，JobTracker HA も結局実装されずじまいでした．CDH に入っている JobTracker HA は，デーモン間でジョブの細かいステートは共有せず，ジョブを最初からやり直すための仕組みとなっています)．このため，Resource Manager High Availability という機能を現在コミュニティと実装している最中です．


##  Resource Manager High Availability 

さて，ようやく本題です．RM HA ですが，概要とSingle Node 上での動かし方について説明します．現在，RM HA は開発中で，圧倒的にドキュメントが不足しています．現在のところ，CDH5 の RM-HA のドキュメントが最も質が高く，まとまっています(Karthik さんが書いたのかな…?)．今回は CDH でなく，trunk の RM を動かしてみます(なので，設定の細かい値は変更される可能性があります．ご了承ください)．

### 概要

Resource Manager は，実行中に以下の情報をメモリに保持しています．

* 実行中のアプリケーション(ジョブ)の状態
* 認証情報 

RM をフェールオーバするには，これらの情報をいずれかの場所に保持しておく必要があります．これらの情報を保持しておくための Store を RMStateStore といいます．

最新 RM では，バックエンドに 4 種類の RMStateStore を選択することができます．NullRMStateStore/MemoryRMStateStore/FileSystemRMStateStore/ZKRMStateStore です．標準値は NullRMStateStore になっており，メモリ上にも保持されません．MemoryRMStateStore はメモリ上に保持するためのものですが，当然 RM が落ちるとその情報は消えてしまいます．よってこれを利用することはないでしょう．FSRMStateStore は，yarn.resourcemanager.fs.state-store.uri で設定されている FileSystem に情報を書き込みます．これは file:/// と設定してあればローカルのハードディスクにもなり得ますし，hdfs:/// と設定してあれば HDFS 上のディレクトリにもなり得ます(動作は未確認)．ZKRMStateStore は，RMStateStore として ZooKeeper にデータを保存します．

FileSystemRMStateStore と ZMRMStateStore のどちらを利用するかは，微妙な問題です．データの管理方法やリソースプランニング上の制約にも依りますが，AttemptId の数分だけファイルが生成されることを考えると，NameNode のメモリ利用量が多くなってしまいますから，HDFS にデータを配置するのは得策とは言えないように思います．よって， ZooKeeper が良いと私は考えます．

RM の状態には，active/standby があります．standby 状態の RM は，listen を行いません．なので，現状では正しく設定されているかどうかの状態の確認が難しいです(これは私が動かしてみて気付いた欠点なので，後でdry-run 的な機能を提案して追加する予定です)．例えば，RM の設定が誤っていても，standby 状態にはなります．フェールオーバした後で binding exception になってしまったりすることがあり得ます．

RM HA を有効にした設定の場合，standby で起動します．standby から active に移行するための管理ツールとして，yarn という名前のツール用います(Apache の場合は bin/yarn)．bin/yarn を実行すると，rmadmin という管理ツールが入っています．例えば， bin/yarn rmadmin -transitionToActive [RM-ID] を実行すると，指定した RM が active 状態に遷移し，動作を開始します．[RM-ID] はユーザが決定する RM の識別子です．

### ZK の設定

今回は，気軽に試すために /tmp に zookeeper のデータを保存するという大変危険な設定を用います．本番環境では使わないでください．

```
$ cat conf/zoo.cfg 
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial 
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just 
# example sakes.
dataDir=/tmp/zookeeper
# the port at which the clients will connect
clientPort=2181
#
# Be sure to read the maintenance section of the 
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
```

    # ZK を Single Node で立ち上げ
    bin/zkServer.sh start


### Single Cluster 上での設定

設定ファイルはコチラ→ https://gist.github.com/oza/7055279
 
    # RM 起動
    sbin/yarn-daemon.sh start resourcemanager
    # NodeManager 起動
    sbin/yarn-daemon.sh start nodemanager
    # RM を active に遷移させる
    bin/yarn rmadmin -transitionToActive rm1

後半の設定項目がかなり説明不足の感がありますが，ここまでの設定で，RM HA が有効になった状態でジョブの実行が可能となりました．

## まとめと今後

後半が説明になっていないような気がするので，その辺りの話を 12/20 に開催される Hadoop Source code Reading でしようかと思います．登録はこちら→からどうぞ．
https://www.eventbrite.com/e/hadoop-15-tickets-9644265257

12日目はbrfrn169さんです．宜しくお願いします:-)