本記事は、Hadoop のマスターコンポーネントである NameNode の HA の仕組みについて説明しています。
Hadoop についてある程度の知識があり、NameNode HA の仕組みについて詳しく知りたい人向けの内容となっています。
なお、本記事の内容は、Hadoop2系(HDP 2.4.2.0)で確認した内容となっておりますので、最新バージョンとの差分が多少ある可能性がありますので予めご了承ください。
Hadoop用語説明
本記事内で登場するHadoopの用語については以下をご参照ください。
用語 |
説明 |
Hadoop |
クラスタを構築することでビッグデータの蓄積、処理を容易に行うことができるツール |
HDFS |
Hadoop内のデータ蓄積を行うコンポーネント |
NameNode |
ファイルシステム(HDFS)のメタデータを管理するマスターコンポーネント |
DataNode |
NameNodeの命令通りにブロックという単位でデータを格納するコンポーネント |
Zookeeper |
クラスタのメタデータ管理機能を提供するコンポーネント |
ZKFC |
ZooKeeper FailOver Controllerの略称で、NameNodeの状態を監視、管理するコンポーネント |
JournalNode |
Standby NameNodeのメタデータをActive NameNodeのものと同期させるためのコンポーネント |
基本的なHadoopクラスタ構成図
Hadoop の主要コンポート構成は以下のとおりです。
図のとおり、HDFS におけるマスターコンポーネントである NameNode は HA 構成にしておくことがベストプラクティスとなります。
では、なぜ NameNode を HA 化しておく必要があるのでしょう?
NameNode HA化の必要性
NameNode は、どのブロック(データ)がどの DataNode 上にあるか等のメタデータを管理しているため、シングル構成の NameNode に障害が発生すると HDFS 上の全てのデータ操作が行えなくなります。
NameNode の起動に必要な edits , fsimage の出力先を冗長化したり、バックアップを作成する運用も可能ですが、NameNode に障害が発生した場合、手動で復旧させる必要があるため復旧までに時間を要してしまいます。
また、NameNode ダウン中に行われていた処理は基本的にエラーとなり、処理を再実行するなどの手間が生じます。
以上のことから、NameNode の HA 化が必要となります。
NameNode を HA 化することで、Active-Standby 構成となり Active NameNode で障害が発生した際には自動でフェイルオーバーが行われ、Standby だった NameNode が Active に昇格します。
NameNode HA 構成のロジック
HA 化構成の NameNode は以下の図のようなロジックで機能します。
NameNode HA構成正常時の動き
NameNode HA 構成では、正常時以下のような動きをします。
- ブロックレポートの送信
- DataNode はブロックレポートを Active、Standby 両方の NameNode に送付します。
- edits ファイルの書き込み
- Active NameNode は JournalNode に edits を書き込みます。
- この時、過半数の JournalNode から書き込み完了の応答があれば書き込み成功となります。
- edits ファイルの取得
- Standby NameNode は JournalNode から edits ファイルを取得します。
上記3つの処理によって、Active、Standby 両方の NameNode のメモリ上に最新のメタデータがある状態となるため、障害の際に Active から Standby にフェイルオーバーした際、Standby だった NameNode はすぐに Active NameNode として機能することができます。
NameNode HA 異常検知の仕組み
次に Active NameNode の障害を検知し、フェイルオーバーする際の動きを説明していきます。
- ヘルスチェック
- NameNode は、ZooKeeper FailOver Controller(以下、ZKFC)の HealthMonitor のヘルスチェック機能によって状態を監視されます。
- ZKFC によるセッション管理
- HealthMonitor によるヘルスチェックの結果、NameNode の状態が「正常」であれば ZKFC は ZooKeeper とのセッションを維持します
- 逆に NameNode の状態が「異常」であれば ZooKeeper とのセッションを切断します。
なお、ZKFC は、NameNode の状態に応じて以下のようなステータスを取得します。
ステータス |
意味 |
SERVICE_HEALTHY |
NameNodeは正常 |
SERVICE_NOT_RESPONDING |
NameNodeからの応答タイムアウト |
SERVICE_UNHEALTHY |
NameNodeは起動しているが正常ではない |
ログにも以下のようにヘルスチェックで取得した NameNode のステータスが出力されていることが確認できます。
Active NameNode が作成するznodeについて
Active NameNode が作成する znode*1 は以下の2種類あります。
- 一時znode(ActiveStandbyElectorLock)
- NameNode は起動時、ZooKeeper に一時 znode を作成します。
- 一時 znode の作成に成功した NameNode が Active となり、残りの NameNode が一時 znode の作成を試みても、既に一時 znode が存在しているため作成できません。
- 一時 znode 作成不可は、既に Active NameNode が存在することを意味します。また、一時 znode は ZooKeeperとのセッションが切れると消滅します。
- 永続znode(ActiveBreadCrumb)
- Active NameNode は永続的な znode を保持します。
- 永続 znode には Active NameNode のホスト名、ZKFC ポート、Nameservice ID、NameNode ID などの情報が記載されています。
下記のログから、Active NameNode は自身が最新の Active であることを示すために /Hadoop-ha 配下にある永続 znode の情報を自身の情報に書き換えていることが分かります。
NameNode HA構成 フェイルオーバー時の動き
Active NameNode に障害が発生し、Standby NameNode が Active に昇格するまでの動きを説明していきます。
- Active NameNode のプロセスダウン
- 今回は、Active である NameNode#1のプロセスダウンが発生したとします。
- ZKFC によるヘルスチェックで、NameNode の異常(SERVICE_NOT_RESPONDING)を検知します。
- ZooKeeperとのセッション断
- NameNode の異常を検知した ZKFC は ZooKeeper とのセッションが切れます。
- 一時znodeの消滅
- ZKFC と Zookeeper 間のセッションが切れたことにより、NameNode#1が作成した一時znode が消滅します。
- Standby NameNode による一時 znode の作成
- Standby である NameNode#2 は、一時znode の作成を試み、成功すると Active になる権利を得えます。
- 永続znodeの情報書き換え
- NameNode#2は自身が最新の Active であることを示すため永続znode の情報を書き換えます。
- Standby から Active への昇格
- 1~5の過程を経て Standby だった NameNode#2 が Active 昇格し、Hadoopクラスタは正常に稼働し続けます。
基本的なフェイルオーバーの流れは上記のとおりですが、万が一 下図のように Active NameNode の状態が正常なのに、ZKとのセッションが切れてしまったらどうなるでしょうか?
- ZooKeeperとのセッション断
- Active NameNode 側の ZKFC と ZooKeeperとのセッションが何らかの理由で切れたと仮定します。
- 一時znodeの消滅
- 前述したとおり、ZooKeeperとのセッションが切れたことにより、一時znode が消滅します。
- Standby NameNode による一時 znode の作成
- Standby NameNode は一時znode の作成を試み、作成に成功する事で Active に昇格します。
結果、上の図のようにActive NameNode が2つになり、スプリットブレイン*2 が発生する懸念がありますが、これを防ぐため、Standby NameNode が Active に昇格する前に、永続znode の情報を読み込み、今まで誰が Active NameNode だったのかをチェックします。
そして、今まで Active だった NameNode に対しフェンスを行い強制的に切り離します。
これにより、Active NameNode は必ず1つとなります。
以下のログからもそのような動きをしていることが読み取れます。
また、万が一スプリットブレインが発生し、Active NameNode が2つになってしまった場合でもデータの不整合が起きないよう「エポック番号」という仕組みを持っています。
エポック番号とは
Active の NameNode は HDFS に対する書き込み操作を edits ファイルに記録し、それを Journal NameNode に書き込みます。
万が一、Active NameNode が2つになり、2つの NameNode が edits ファイルを JournalNode に書き込んでしまうとデータの不整合が発生する可能性があります。
それを防ぐため、NameNode はエポック番号を持っており、フェイルオーバー等で Active になる度に以下の図のようにエポック番号が1ずつ増えていきます。
上記の仕組みにより、最も大きなエポック番号を持っている NameNode が最新の Active NameNodeとなります。
また、3台の JournalNode も最新のエポック番号を保持しており、万が一2つのNameNode から edits ファイルの書き込み要求があったとしても、エポック番号が一致している NameNode からの要求しか受け付けません。
この仕組みにより、JournalNode に edits ファイルを書き込める NameNode は必ず1つとなり、データの整合性が守られます。
意図的にフェイルオーバーを発生させると以下のようにエポック番号が増えていく様子が分かります。
また、JournalNode の以下のファイルを確認すると、JournalNode が最新のエポック番号を保持をしていることが分かります。
最後に
今回は Hadoop の NameNode HA 構成について、必要性と仕組みについて説明させていただきました。
JBS では、これまでに様々なお客様の Hadoopに関するプロジェクトに多く携わり、現在も Hadoop を利用しているお客様および、Hadoop を利用したいお客様からの引き合いがあります。
そのため、Hadoop エンジニアを育成するための社内向けのトレーニングを作成して取り組んでおります。
Hadoop トレーニングは以下のような3ステップ実施する構成になっています。
用意された課題に取り組み、得た知識を有識者にアウトプットすることで理解を深める形式で実施しています。
※社外向けのトレーニングは実施しておりません
*1:Znodeとは、ZooKeeperにおける、数バイト~数キロバイトの小規模なデータを持つファイルシステムに似たデータレジスタの事です。
*2:スプリットブレインとは、セッションが切れるなどの原因でノード間の疎通が取れなくなった際にStandbyノードがActiveに昇格することにより、同一環境内に本来複数存在してはならないActiveノードが複数発生してしまう状態のことです
権田 祐樹(日本ビジネスシステムズ株式会社)
これまで Linux/Ansible/Hadoop/AWS/Azure/Snowflake/Apache NiFi などに携わり、データ活用に必要となるデータ分析基盤の設計/構築および、パイプライン開発などを経験しました。趣味は映画鑑賞で、ここ数年はマーベル作品にハマってます。
担当記事一覧