1. Zookeeperの基礎知識
ZooKeeper の概要
Zookeeper は、分散調整サービス用のオープンソース フレームワークです。これは主に、分散クラスター内のアプリケーション システムの一貫性の問題を解決するために使用されます。
ZooKeeper は本質的に、分散型の小さなファイル ストレージ システムです。ファイル システムと同様のディレクトリ ツリーに基づいてデータ ストレージを提供し、ツリー内のノードを効果的に管理できます。これは、保存されたデータの状態変化を維持および監視するために使用されます。これらのデータ状態の変化を監視することで、データベースに基づいたクラスタ管理を実現できます。
ZooKeeper特性
- グローバル データの一貫性: クラスター内の各サーバーはデータの同じコピーを保存します。クライアントがどのサーバーに接続しても、表示されるデータは一貫しています。これが最も重要な機能です。
- 信頼性: メッセージがいずれかのサーバーで受け入れられた場合、そのメッセージはすべてのサーバーで受け入れられます。
- シーケンス: グローバル順序と部分順序を含む: グローバル順序とは、1 つのサーバー上でメッセージ a がメッセージ b より前にパブリッシュされる場合、メッセージ a はすべてのサーバー上でメッセージ b より前にパブリッシュされることを意味します。部分的順序とは、メッセージ b がサーバーによってパブリッシュされる場合を意味します。メッセージ a の後の送信者が同じ場合、a は b の前になければなりません。
- データ更新のアトミック性: データ更新は成功する (ノードの半分以上が成功する) か失敗し、中間状態はありません。
- リアルタイム: Zookeeper は、クライアントが一定時間内にサーバー更新情報またはサーバー障害情報を取得することを保証します。
ZooKeeper クラスターの役割
リーダー:
Zookeeper クラスターの作業の中核
トランザクション リクエスト (書き込み操作) の唯一のスケジューラおよびプロセッサであり、クラスタ トランザクション処理の順序を保証します。
クラスター内の各サーバーのスケジューラ。
create、setData、delete などの書き込み操作のリクエストは、処理のためにリーダーに転送する必要があります。リーダーは番号を決定して操作を実行する必要があります。このプロセスはトランザクションと呼ばれます。
フォロワー:
クライアントの非トランザクション (読み取り操作) リクエストを処理し、トランザクションリクエストをリーダーに転送します。
クラスターリーダー選挙の投票に参加します。
さらに、訪問者数が比較的多い飼育員クラスターの場合は、オブザーバーの役割を追加することもできます。
観察者:
オブザーバー ロールは、Zookeeper クラスターの最新の状態変化を監視し、これらの状態を同期します。非トランザクション要求を独立して処理し、トランザクション要求を処理のためにリーダー サーバーに転送できます。
いかなる形式の投票にも参加せず、非トランザクション サービスのみを提供します。これは通常、クラスターのトランザクション処理能力に影響を与えることなく、クラスターの非トランザクション処理能力を向上させるために使用されます。
ZooKeeper クラスターの構築
Zookeeper クラスターの構築とは、ZooKeeper 分散モードのインストールを指します。通常、2n+1 台のサーバーで構成されます。これは、(Paxos アルゴリズムの実装に基づく) リーダー選挙が過半数によって支持されることを保証するために、ZooKeeper クラスターの数が通常奇数であるためです。
Zookeeper の実行には Java 環境が必要なため、事前に jdk をインストールする必要があります。リーダー+フォロワー モードがインストールされているクラスターの場合、一般的なプロセスは次のとおりです。
- ホスト名から IP アドレスへのマッピング構成を構成する
- ZooKeeper 構成ファイルを変更する
- 配布インストール ファイルをリモートでコピーする
- 私のIDを設定します
- ZooKeeper クラスターを開始する
オブザーバー モードを使用する場合は、対応するノードの構成ファイルに次の構成を追加できます。
ピアタイプ=オブザーバー
次に、構成ファイルでどのノードをオブザーバーとして指定するかを次のように指定する必要があります。
サーバー.1:ノード1:2181:3181:オブザーバー
詳細な手順については、添付のインストール文書を参照してください。
2. ZooKeeper シェル
クライアント接続
zkCli.sh –server ip を実行してコマンド ライン ツールに入ります。
help と入力して、zk シェル プロンプトを出力します。
シェルの基本操作
ノードを作成する
[-s] [-e] パス データ ACL を作成します
このうち、-s または -e はそれぞれノードの特性 (順次ノードまたは一時ノード) を指定します。指定しない場合は永続ノードを意味します。acl は権限制御に使用されます。
シーケンス ノードを作成します。
一時ノードを作成します。
永続ノードを作成します。
読み取りノード
読み取りに関連するコマンドには、ls コマンドと get コマンドが含まれます。ls コマンドは、Zookeeper の指定されたノードの下にあるすべての子ノードをリストできます。また、指定されたノードの下にある最初のレベルのすべての子ノードのみを表示できます。get コマンドは、次のコマンドを取得できます。 Zookeeper の指定されたノードの子ノード データの内容と属性情報。
ls パス [監視]
パスを取得 [監視]
ls2 パス [監視]
ノードを更新する
パスデータを設定 [バージョン]
data は更新される新しいコンテンツ、version はデータのバージョンを表します。
現在、dataVersion は 1 に変更されており、更新されたことを示しています。
ノードの削除
パス[バージョン]を削除します
削除されたノードに子ノードがある場合、そのノードは削除できません。最初に子ノードを削除し、次に親ノードを削除する必要があります。
RMRパス
ノードは再帰的に削除できます。
クォータ
setquota -n|-b val path ノードの制限を増やします。
n: 子ノードの最大数を示します。
b: データ値の最大長を示します。
val: 子ノードの最大数またはデータ値の最大長
パス: ノードパス
listquota path は、指定されたノードのクォータをリストします。
子ノードの数は 2 で、データ長 -1 は制限なしを意味します。
delquota [-n|-b] パス クォータの削除
他のコマンド
History : コマンド履歴をリストします。
redo: このコマンドは、指定したコマンド番号の履歴コマンドを再実行でき、履歴からコマンド番号を確認できます。
3. ZooKeeper データモデル
ZooKeeper のデータ モデルは、標準ファイル システムの構造と非常によく似ています。階層的な名前空間があり、ツリー階層を採用しています。ZooKeeper ツリー内の各ノードは Znode と呼ばれます。ファイル システムのディレクトリ ツリーと同様に、ZooKeeper ツリー内の各ノードは子を持つことができます。しかし、違いもあります。
- Znode は、ファイルとディレクトリの両方の特性を備えています。ファイルのようにデータ、メタ情報、ACL、タイムスタンプなどのデータ構造を保持するだけでなく、ディレクトリのようにパス識別子の一部として使用したり、サブZnodeを持つこともできます。ユーザーは、Znode の追加、削除、変更、確認などの操作を行うことができます (許可が必要です)。
- Znode にはアトミック操作があり、読み取り操作ではノードに関連するすべてのデータが取得され、書き込み操作ではノードのすべてのデータも置き換えられます。さらに、各ノードには独自の ACL (アクセス制御リスト) があり、ユーザーの権限を指定します。つまり、特定のユーザーがターゲット ノードで実行できる操作を制限します。
- Znode ストレージのデータ サイズには制限があります。ZooKeeper は一部のデータを関連付けることができますが、従来のデータベースやビッグ データ ストレージとして設計されたものではなく、分散アプリケーションにおける設定ファイル情報、ステータス情報、収集場所などのスケジュール データを管理するために使用されます。これらのデータの共通の特徴は、通常 KB 単位の非常に小さなデータであることです。ZooKeeper のサーバーとクライアントはどちらも、各 Znode のデータ サイズを厳密にチェックして最大 1M に制限するように設計されており、通常の使用ではこの値よりも大幅に小さくなるはずです。
- Znode は、Unix のファイル パスのように、パスによって参照されます。パスは絶対パスである必要があるため、スラッシュ文字で始める必要があります。さらに、これらは一意である必要があります。つまり、各パスは 1 つの表現のみを持つため、これらのパスは変更できません。ZooKeeper では、パスは Unicode 文字列で構成されますが、いくつかの制限があります。文字列「/zookeeper」は、キー クォータ情報などの管理情報を保存するために使用されます。
データ構造図
グラフ内の各ノードは Znode と呼ばれます。各 Znode は 3 つの部分で構成されます。
① stat: Znode のバージョン、権限、その他の情報を説明するステータス情報です。
②データ:Znodeに関連付けられたデータ
③子:Znode配下の子ノード
ノードタイプ
Znode には一時ノードと永続ノードの 2 種類があります。
ノードのタイプは作成時に決定され、変更することはできません。
一時的なノード: ノードの存続期間は、ノードを作成したセッションによって異なります。セッションが終了すると、一時ノードは自動的に削除されますが、もちろん手動で削除することもできます。一時ノードは子ノードを持つことができません。永続ノード: ノードのライフサイクルはセッションに依存せず、クライアントが明示的に削除操作を実行した場合にのみ削除できます。
Znodeにはシリアル化機能もあり、作成時に指定すると、Znodeの名前に連続的に増加するシリアル番号が自動的に付加されます。シーケンス番号はこのノードの親ノードに固有であるため、各子ノードが作成された順序が記録されます。形式は「%10d」(10桁、「0000000001」のように値のない桁は0で補われます)です。
このようにして、以下に対応する 4 種類の Znode ノードが存在します。
PERSISTENT: 永続ノード
EPHEMERAL: 一時的なノード
PERSISTENT_SEQUENTIAL: 永続ノード、シリアル化
EPHEMERAL_SEQUENTIAL: 一時ノード、シリアル化
ノードのプロパティ
各 znode には一連の属性が含まれており、ノードの属性は get コマンドを通じて取得できます。
dataVersion: データのバージョン番号。ノード上で設定操作が実行されるたびに、dataVersion の値が 1 ずつ増加します (同じデータが設定されている場合でも)。これにより、データの更新時に発生する順序の問題を効果的に回避できます。
cversion : 子ノードのバージョン番号。znode の子ノードが変更されると、cversion の値が 1 増加します。
cZxid : Znode によって作成されたトランザクション ID。
mZxid: 変更される Znode のトランザクション ID、つまり mZxid は、znode が変更されるたびに更新されます。
zk の場合、変更ごとに一意のトランザクション ID、zxid (ZooKeeper トランザクション ID) が生成されます。zxid を通じて、更新操作の順序を決定できます。たとえば、zxid1 が zxid2 より小さい場合、zxid1 操作が zxid2 より前に発生し、操作が異なる znode であっても、zxid は zk 全体で一意であることを意味します。
ctime: ノードが作成されたときのタイムスタンプ。
mtime: ノードの最新の更新が行われたときのタイムスタンプ。
ephemeralOwner: ノードが一時ノードの場合、ephemeralOwner 値はノードにバインドされたセッション ID を示します。そうでない場合、ephemeralOwner 値は 0 です。
クライアントとサーバーが通信する前に、まず接続を確立する必要があります。これはセッションと呼ばれます。接続の確立後、接続タイムアウトが発生したり、認証が失敗したり、接続が明示的に閉じられた場合、接続は CLOSED 状態になり、この時点でセッションは終了します。
4. ZooKeeper Watcher (監視メカニズム)
ZooKeeper は、分散データのパブリッシング/サブスクライブ機能を提供します。一般的なパブリッシュ/サブスクライブ モデル システムは、1 対多のサブスクリプション関係を定義し、複数のサブスクライバーがトピック オブジェクトを同時に監視できるようにします。トピック オブジェクト自体が変更されると、すべてのサブスクライバーに通知されます。彼らがそれに応じて行動できるように。
ZooKeeperでは、この分散通知機能を実現するためにWatcher機構を導入しています。ZooKeeperでは、クライアントがサーバーにWatcherを登録することができ、サーバー上の何らかのイベントがWatcherをトリガーすると、指定したクライアントにイベント通知が送信され、分散通知機能を実現します。
トリガー イベントには、ノードの作成、ノードの削除、ノードの変更、子ノードの変更など、さまざまなタイプがあります。
一般に、Watcher は次の 3 つのプロセスとして要約できます。クライアントが Watcher をサーバーに登録し、サーバー イベントが Watcher をトリガーし、クライアントが Watcher をコールバックしてトリガー イベントを取得します。
時計の仕組みの特徴
ワンタイムトリガー
イベントによって監視がトリガーされると、監視を設定したクライアントにウォッチャー イベントが送信されます。この効果は 1 回限りです。後で同じイベントが再度発生しても、再度トリガーされることはありません。
イベントのカプセル化
ZooKeeper は WatchedEvent オブジェクトを使用してサーバー側イベントをカプセル化し、配信します。
WatchedEvent には、各イベントの 3 つの基本プロパティが含まれています。
通知状態 (keeperState)、イベント タイプ (EventType)、およびノード パス (path)
非同期で送信されたイベント
ウォッチャーの通知イベントはサーバーからクライアントに非同期的に送信されます。
トリガーする前に登録する
Zookeeper の監視メカニズムの場合、クライアントは最初にサーバーにアクセスして監視を登録する必要があります。これにより、イベントの送信によって監視がトリガーされ、クライアントに通知されます。
通知ステータスとイベントの種類
同じイベント タイプでも、通知状態が異なれば意味も異なります。次の表に、一般的な通知状態とイベント タイプを示します。
このうち、接続状態イベント (type=None、path=null) は、クライアントが直接処理する必要がある場合には、クライアントが登録する必要はありません。
シェルクライアント設定ウォッチャー
ノードのデータ変更監視を設定します。
別のクライアント経由でノード データを変更します。
この時点で、リッスンするように設定されているノードは通知を受け取ります。
5. Zookeeper の典型的なアプリケーション
データのパブリッシュ/サブスクライブ
データ発行/購読システムは、いわゆる構成センターです。つまり、発行者はデータを ZooKeeper のノードに発行し、購読者にデータ購読を提供して、データを動的に更新するという目的を達成し、データの集中管理を実現します。構成情報とデータ収集、動的更新。
ZooKeeper はプッシュとプルの組み合わせを採用しており、クライアントは注意が必要なノードをサーバーに登録し、ノードのデータが変更されると、サーバーは対応するクライアントに Watcher イベント通知を送信し、クライアントはそれを受け取ります。その後、サーバーから最新のデータを取得する必要があります。
主に使用されるもの: 監視メカニズム。
クラスター選択を提供する
分散環境では、マスター/スレーブ アーキテクチャのクラスターであっても、アクティブ/スタンバイ アーキテクチャのクラスターであっても、サービス中に通常の外部サービス (マスターと呼ばれます) が存在する必要があります。
マスターに障害が発生した場合は、新しいマスターを再選出する必要があります。サービスの継続的な可用性を確保します。Zookeeper はそのような機能的なサービスを提供できます。
主に使用されるもの: znode の一意性、一時的なノードの一時性、監視メカニズム。
分散ロック
ZooKeeper はデータ ノードを介したロックを表します。たとえば、/itcast/lock ノードはロックを定義できます。すべてのクライアントは create() インターフェイスを呼び出して、/itcast の下にロックの子ノードを作成しようとしますが、ZooKeeper の強力な一貫性により、すべてのクライアントを確認してください。最終的には 1 つのクライアントだけが正常に作成されます。つまり、ロックが取得されたと考えられ、他のスレッドウォッチャーが子ノードの変化を監視しています(ロックの解放を待ってリソースを奪い合います)。
さらに、znode のシリアル化機能を使用して、znode を作成するクライアントに自動的に番号を付けることができ、いわゆるシーケンシャル ロックの機能を実現できます。