【ITニュース解説】Apache Zookeeper: O coordenador de sistemas distribuídos
2025年09月28日に「Dev.to」が公開したITニュース「Apache Zookeeper: O coordenador de sistemas distribuídos」について初心者にもわかりやすく解説しています。
ITニュース概要
Apache Zookeeperは、複数のコンピューターが連携する分散システムにおいて、設定情報の一元管理、システム間の同期、リーダー選出、サービス発見を助ける中央集権型サービスだ。これにより、複雑な分散環境での課題を解決し、Apache Kafkaなどのシステムで安定稼働を支えている。
ITニュース解説
Apache ZooKeeperは、複数のコンピューターが連携して動作する「分散システム」と呼ばれる環境において、それらのコンピューターがバラバラにならず、きちんと足並みを揃えて協力し合えるように調整役を務める重要なサービスである。Yahoo!で開発され、その後Apacheプロジェクトのトップレベルとなり、特に大量のデータを扱う「ビッグデータ」の分野で広く使われている。
分散システムでは、複数のコンピューター(「ノード」と呼ぶ)が一緒に動くため、様々な課題に直面する。例えば、たくさんのKafkaブローカーの中から誰か一人を「リーダー」に選ぶとき、どのブローカーも自分がリーダーだと主張してしまい、システムが混乱してしまう「リーダー選出問題」がある。また、複数のサービスが共通の設定情報を使う場合、それぞれのサービスが独自のコピーを持っていると、どれか一つを更新しても他のサービスに伝わらず、情報が食い違う「設定管理問題」も起きる。さらに、サービスAがサービスBと通信したいとき、Bがどこにいるか見つけられない「サービス発見問題」もある。
ZooKeeperはこれらの問題を解決するために設計されている。リーダー選出問題では、ZooKeeperが提供する「合意アルゴリズム」によって、複数のブローカーの中から確実にただ一人のリーダーを選び出し、他のブローカーはそのリーダーに従うことができる。設定管理問題では、ZooKeeperに設定情報を一元的に保存することで、すべてのサービスが常に最新の同じ設定を使うことができ、設定が変更されたら自動的に各サービスに通知することも可能だ。サービス発見問題では、各サービスがZooKeeperに自分の存在を登録し、他のサービスはZooKeeperに問い合わせることで、動的に相手を見つけ出すことができる。
ZooKeeperが存在しない場合、静的な設定ファイルを使ったり、普通のデータベースを使ったりする方法もあるが、これらは分散システムの課題解決には不向きだ。静的な設定ファイルでは、手動での変更が必要で、サービスを再起動しないと反映されず、設定の不整合が起きやすい。また、システム全体の協調や障害検知の仕組みもない。リレーショナルデータベースを使う方法も考えられるが、データベース自体が単一障害点となりやすく、全ての操作でSQLクエリが必要なため遅延が発生しやすく、分散環境での複雑なトランザクション管理や高い拡張性には限界がある。
ZooKeeperは、データをファイルシステムに似た階層構造で管理する。これは「znode」(ズーノード)と呼ばれるノードで構成され、ディレクトリのようにデータを整理できる。例えば、Kafkaのブローカー情報やトピックの設定情報などがこの構造で保存される。znodeにはいくつかの種類がある。一度作ると明示的に削除するまで残り続ける「永続ノード」は設定情報などに使われる。接続が切れると自動で削除される「エフェメラルノード」は、サービスが現在稼働しているかどうかの確認や、リーダーの存在を示すために使われる。さらに、作成時にユニークな連番が自動的に付与される「シーケンシャルノード」は、リーダー選出の順番待ちやキューの実装に使われる。
ZooKeeperの核となるのは、「Zab(ZooKeeper Atomic Broadcast)」という合意アルゴリズムだ。これは、複数のZooKeeperサーバー(「アンサンブル」と呼ぶ)が常に同じ状態を保つための仕組みだ。まず、アンサンブルの中から一人の「リーダー」が選ばれる。次にリーダーは、他の「フォロワー」サーバーからシステムの現在の状態を収集し、全員を同じ状態に同期させる。その後、クライアントからの書き込みリクエストはすべてリーダーが処理し、その結果をフォロワーに複製する。これにより、たとえ一部のサーバーに障害が発生しても、システム全体としてデータの整合性を保ちながら動作し続けることができる。
特に、Apache KafkaではZooKeeperが重要な役割を担ってきた。Kafkaブローカーは起動時にZooKeeperに自分自身を登録し、エフェメラルノードを使って接続を維持する。もしブローカーが停止すると、ZooKeeper上のエフェメラルノードが自動的に削除され、他のブローカーはZooKeeperからその変更を通知され、障害を検知できる。また、Kafkaクラスター全体を管理する「コントローラー」の選出もZooKeeperが行う。複数のブローカーが同時にコントローラーになろうとしても、ZooKeeperのエフェメラルノード作成機能により、成功したブローカーだけがコントローラーとなる。Kafkaのトピックの構成情報やパーティションのリーダー・レプリカの情報といった重要なメタデータもZooKeeperに保存され、Kafkaクラスターの円滑な運用を支えていた。
ZooKeeperは通常、「アンサンブル」と呼ばれる複数のサーバーのクラスターとしてデプロイされる。このクラスターは通常、3台、5台、7台といった奇数で構成される。これは、システムが停止せずに動き続けるために、常に過半数のサーバーが稼働している必要があるからだ(「クォーラム」の維持)。書き込みリクエストはリーダーが処理し、読み取りリクエストはリーダーまたはフォロワーが処理できる。クライアントはZooKeeperサーバーに「セッション」を確立し、ハートビートを定期的に送信して接続を維持する。また、特定のznodeの状態変化(作成、削除、データ変更、子ノード変更など)を監視する「ウォッチャー」を設定することで、クライアントはシステムの状態変化をリアルタイムで受け取ることができる。
ZooKeeperの基本的な設定は「zoo.cfg」というファイルで行い、サーバーの識別やデータの保存場所、クライアント接続ポートなどを指定する。本番環境では、JVMのヒープサイズを増やしたり、ネットワークやディスクの性能を最適化したりといった詳細なチューニングが必要となる。Zookeeperには、コマンドラインクライアントが用意されており、znodeのリスト表示、データの取得・作成・更新・削除など、基本的な操作を行うことができる。また、statやmntrコマンドを使って、サーバーの状態やパフォーマンスメトリクスを監視することも可能だ。
運用上よくあるトラブルには、クライアントがZooKeeperに接続できない「接続問題」、アンサンブルがクォーラムを確立できずシステムが停止してしまう「スプリットブレイン」や「クォーラム問題」、そして処理速度が遅くなる「パフォーマンス低下」がある。これらは、ログの確認、ポートの確認、サーバー間の接続状況の診断、メトリクスの監視などによって診断し、適切に設定を調整したり、リソースを増強したりすることで解決される。
近年、KafkaはZooKeeperの持つ運用上の複雑さや拡張性の限界といった課題を解決するため、「KRaft(Kafka Raft)」という新しいモードを導入した。これは、Kafka自身がRaft合意アルゴリズムを用いてメタデータを管理する仕組みであり、ZooKeeperを不要にするものだ。これにより、管理するコンポーネントが減り、メタデータの処理が高速化され、より高いスケーラビリティが期待される。Kafka 3.3以降で本番利用可能となっており、将来的にはZooKeeperを必要としないKafkaが主流となるが、現在でも多くのプロダクション環境でZooKeeperがKafkaを支えている。
Kafka以外にも、ZooKeeperはさまざまな分散システムで活用されている。例えば、サービスが自身の存在をZooKeeperに登録し、他のサービスがそれを検索することで、動的にサービスを発見する仕組みを構築できる。また、アプリケーションの設定情報をZooKeeperに一元管理し、変更があれば全サービスに自動通知する分散設定システムとしても利用される。さらに、複数のサーバーが共有リソースにアクセスする際に、競合が発生しないように排他的に制御する「分散ロック」の実現にも使われる。
ZooKeeperを本番環境で運用する際には、適切なサーバー数(通常は5台)と十分なハードウェアリソース(CPU、RAM、高速なSSD)を確保することが重要だ。セキュリティ面では、SASL/Kerberosを使った認証や、アクセス制御リスト(ACL)による認可を設定することで、不正アクセスを防ぐ。また、データが破損した場合に備え、定期的なデータのバックアップと、障害発生時の迅速なリカバリ手順を確立しておくことも不可欠である。
Apache ZooKeeperは、分散システムの複雑な課題を解決し、複数のコンピューターが協力して安定稼働するための信頼性の高い基盤を提供する。Kafkaのような大規模なシステムを支えるその役割は非常に大きく、分散システムを理解する上で不可欠な技術の一つと言える。