Hadoop yarnの各ノードのメモリ管理
yarnはmr1と色々と変わっているのですが、まず各ノードにおけるメモリの設定についてまとめます。
なお、CDH4.1.2で試した結果ですので、最新のバージョンとは挙動が異なる可能性があります。
# まとめるのをサボっていた結果既にCDH4.2がリリースされています(汗
メモリ管理の基本
yarnではapplication master(以下AM)やmapper, reducerを総称して「コンテナ」と呼び、「各コンテナが利用すると想定する物理メモリ量」をmapred-site.xmlの以下の項目で設定します。
- yarn.app.mapreduce.am.resource.mb => AMが使用するとするメモリ
- mapreduce.map.memory.mb => mapperが使用するとするメモリ
- mapreduce.reduce.memory.mb => reducerが使用するとするメモリ
ResourceManager(以下RS)は上記設定を元に、各ノードでyarn-site.xmlのyarn.nodemanager.resource.memory-mbで指定した物理メモリ量の超えないようにコンテナを起動していきます。
例えば次のような設定をした場合、
- yarn.nodemanager.resource.memory-mb = 8192
- yarn.app.mapreduce.am.resource.mb = 2048
- mapreduce.map.memory.mb = 1024
- mapreduce.reduce.memory.mb = 2048
そのノードでのコンテナの起動パターンには以下のようなモノが考えられます。
- mapperだけ8個
- reducerだけ4個
- AM1個 + reducer2個 + mapper2個
- 他アレコレ。
どのようなパターンでコンテナが起動しても最終的にyarn.nodemanager.resource.memory-mbだけしかメモリを使わないと考えることができるので、全体としてのメモリ使用量の見積もりは簡単になります。
注意点その1
上記のように各ノードごとの最大同時起動コンテナ数が決定されるので、CPUのコア数等、メモリ以外のリソースも考慮して、各設定項目はバランス良く設定をすべきです。
駄目な例として、yarn.nodemanager.resource.memory-mbを多めにとって、各コンテナの想定量が少ないままだと、特定ノードでコンテナ起動が集中して、パフォーマンスも出ないし、全然分散処理できないという結果につながります。
注意点その2
mapreduce.map.memory.mbなどは「想定する物理メモリ量」と記述したとおり、あくまで「想定量」です。
実際に使用されるメモリが想定量を超えてはいけません。
超えた場合そのコンテナはNodeManager(以下NM)にkillされます。
そのため、メモリ使用想定量を変更する場合は、以下のmapred-site.xmlのjava optsの設定も同時に修正すべきです。
- yarn.app.mapreduce.am.command-opts => AMのjava opts
- mapreduce.map.java.opts => mapperのjava opts
- mapreduce.reduce.java.opts => reducerのjava opts
また想定量は増やさずにheapの設定だけ増やしてしまうのも、同様に問題があるのでやめるべきです。
注意点その3
NMはコンテナで使用している物理メモリだけでなく、仮想メモリも監視しています。仮想メモリの使用想定量は物理メモリの想定量にyarn.nodenamager.vmem-pmem-ratioを乗じたものになります。
NMにコンテナがkillされた場合、物理メモリではなく仮想メモリが想定量を超えてしまっているのが直接のトリガになっているケースもあると思います。
その場合はyarn.nodenamager.vmem-pmem-ratioを修正すればいいのですが、そもそものheapの設定を失敗している可能性もあるので、まず先にheapの設定を確認することをオススメします。
注意点その4
大量のreducerを起動するjobを起動してしまうと、AMとreducerで全リソースを使い切ってしまいmapperが起動できず、reducerは起動できないmapperが終わるのを待つというデッドロックが発生するケースがあるようです。
十分なノード数があればそんなに心配しなくても大丈夫だと思いますが、冗談みたいな数のreducerを起動するjobは、一応注意した方がよいでしょう。