Zookeeper のソースコード分析プロセス

序文

Zookeeper は分散調整サービスとして、ネーミング サービス、構成管理、同期など、分散システム用のいくつかの基本サービスを提供し、開発者が分散問題をより簡単に処理できるようにします。

分散システムでは、調整が重要なタスクです。たとえば、独立したプロセスやマシンのグループにどのようなタスクを実行する必要があるかを知らせる方法、そのステータスを他のプロセスやマシンと同期する方法、障害や例外を処理する方法などです。これらの問題はすべて Zookeeper によって解決されます。

この記事では、Zookeeper の内部実装について、そのさまざまなコンポーネントとインターフェイスから始めて、その動作原理と設計思想を分析して深く理解することができます。このソース コード分析を読む過程で、Zookeeper の動作原理と設計思想を深く理解し、分散問題の解決に Zookeeper をより適切に使用できるようになることを願っています。

動物園の飼育員が始まります

どのようなコードを検討する場合でも、全体の構造と操作プロセスをよりよく理解できるように、プログラムのエントリ ポイントから始める必要があります。

ここに画像の説明を挿入します

スクリプトを通じてzkServer.shスタートアップ クラスを確認できますQuorumPeerMain

ここに画像の説明を挿入します

Zookeeper の起動が main メソッドを通じて開始され、最後にrunFromConfigメソッドが呼び出されて ZooKeeper クラスター ノードをセットアップして起動していることがわかります。

ここに画像の説明を挿入します

上記のコードはQuorumPeer、トランザクション ログとスナップショット ディレクトリのパス、選択アルゴリズムの選択、指定されたサーバー ID、定義されたクロック サイクルとデータ保存インスタンス、その他の構成を設定します。さらに、サーバーおよびクライアント接続用のファクトリ クラス (NIO/Netty) が作成されます。最後に、start メソッドを呼び出してサービスを開始します。

ここに画像の説明を挿入します

ではstart、主に次の 4 つのタスクが完了します。

  1. ディスクからメモリにデータをロードして、後続の処理と応答に必要なデータを確保します。
  2. クライアントのリクエストを処理し、クライアントとの通信と対話を実装するためにソケットを確立します。
  3. リーダー選出の準備を行い、選出アルゴリズムを決定しました。
  4. リーダーの選出を実施し、ノードのステータスを監視してそれに応じて処理し、ノードの障害や異常な状態をタイムリーに検出して処理し、システム全体の信頼性と安定性を確保します。

ディスクデータをロードする

ZooKeeper はメモリ レベルで動作します。信頼性を確保するために、データはトランザクション ログの形式でファイルに保存されるため、データは起動時に最初にメモリにロードされます。

ここに画像の説明を挿入します

このコードの主な目的は、Zookeeper データベースをディスクからメモリにロードし、関連epoch情報を確認して処理することです。getDataTree().lastProcessedZxidこのコード行は、ZooKeeper サーバーで処理された最新のトランザクションを取得しますzxidZxidUtils.getEpochFromZxid(lastProcessedZxid)このコード行は、次zxidからepoch。このコード行は、readLongFromFile(CURRENT_EPOCH_FILENAME)ファイルから現在のepoch情報を読み取ります。zxid所属する値がepoch現在の値より小さい場合epochIOException例外がスローされます。

クライアントとのコミュニケーションと対話

cnxnFactoryサーバーはクライアント要求を受信して​​処理するために確立されますSocket 。下の図のコードは でNIOServerCnxnFactory、別のコードがありますNettyServerCnxnFactoryこのオプションはNIO引き続きNetty構成ファイルで設定できます。詳しい方はNIOネットワークプログラミングのコラムをお読みください。Netty
ここに画像の説明を挿入します

中心となるのはクライアント要求の処理であり、次のプロセッサがあります。

ここに画像の説明を挿入します

  • CommitProcessorこれはトランザクション送信プロセッサであり、プロポーザルが送信されるまで、クラスター内のプロポーザルに対する投票を待ちます。
  • SyncRequestProcessorローカル ディスクへのトランザクション リクエスト (書き込みリクエスト) の永続化を担当します。
  • AckRequestProcessorこれは、リーダーに固有のプロセッサです。その主な役割は、SyncRequestProcessorプロセッサがトランザクション ログの記録を完了した後に、プロポーザルの投票コレクターに ACK フィードバックを送信し、現在のサーバーがプロポーザルのトランザクション ログの記録を完了したことを投票コレクターに通知することです。
  • FollowerRequestProcessorこのプロセッサは、クライアントからの読み取り要求と書き込み要求の処理を担当し、書き込み要求をリーダー ノードに転送するなど、処理のために他のプロセッサに転送します。
  • SendAckRequestProcessorリーダー ノードに確認応答メッセージ (ACK) を送信して、要求が処理されたことをリーダー ノードに通知します。

リーダー選挙の準備

startLeaderElection主な呼び出しは、createElectionAlgorithmクラスタ間ネットワーク接続のマネージャを作成しQuorumCnxManager、選択アルゴリズムを選択することです。これは構成ファイルを通じて構成され、デフォルトは ですFastLeaderElection

ここに画像の説明を挿入します

ノードステータス処理

super.start()実行クラスQuorumPeer.javaのメソッドはrun()主にノードのステータスを監視および処理するために使用されます。

ここに画像の説明を挿入します

Zookeeper の起動時は最初のLooking状態であり、選出によってサーバーの 1 つがリーダーになり、他のサーバーがフォロワーになります。コードを理解するのが難しい場合は、 ZAB プロトコルを参照してください

ここに画像の説明を挿入します

要約する

ソースコードを深く分析することで、そのシンプルさと機能実装の巧妙な設計に気づきました。コードで処理される機能は非常に複雑ですが、構成とコーディング スタイルが単純であるため、非常に読みやすく、理解しやすくなっています。ネットワーク プログラミングの広範な使用、接続のセキュリティと最適化の慎重な扱いには特に注意が払われています。また、ZAB プロトコルが分散一貫性の問題をどのように巧みに解決しているかについても説明されており、これらの繊細な設計概念は間違いなく分散システムの開発に貴重な参考資料を提供します。今後の作業でこれらのアイデアをコードに統合することを楽しみにしています。

おすすめ

転載: blog.csdn.net/qq_28314431/article/details/132939298