史上最も便利な Zookeeper サーバーの構築方法 (推奨)

史上最も便利な Zookeeper サーバーの構築方法 (推奨)

ZooKeeperとは

ZooKeeper は、分散アプリケーションに効率的で可用性の高い分散調整サービスを提供する Apache のトップレベル プロジェクトです。データの公開/サブスクリプション、負荷分散、ネーミング サービス、分散調整/通知、分散ロックなどの分散基本サービスを提供します。 ZooKeeper は、その便利な使い方、優れたパフォーマンス、優れた安定性により、Hadoop、HBase、Kafka、Dubbo などの大規模な分散システムで広く使用されています。

Zookeeper には、スタンドアロン モード、疑似クラスター モード、クラスター モードの 3 つの動作モードがあります。

  • スタンドアロン モード: このモードは、一般的に開発およびテスト環境に適しています。一方では、マシン リソースがそれほど多くなく、他方では、日常的な開発およびデバッグでは非常に優れた安定性が要求されません。
  • クラスター モード: ZooKeeper クラスターは通常、マシンのグループで構成されます。通常、3 台以上のマシンで ZooKeeper クラスターを形成できます。 ZooKeeper クラスターを構成する各マシンは、現在のサーバー状態をメモリ内に保持し、各マシンは相互に通信を維持します。
  • 疑似クラスター モード: これは特別なクラスター モードです。つまり、クラスター内のすべてのサーバーが 1 台のマシンに展開されます。手元に適切なマシンがある場合、それをスタンドアロン モードでデプロイすると、リソースが無駄になります。この場合、ZooKeeper では、異なるポートを開始することで 1 台のマシン上で複数の ZooKeeper サービス インスタンスを開始し、クラスター特性を持つ外部サービスを提供できます。

ZooKeeper関連の知識

  • Zookeeper のリーダー: 投票の開始と解決、システム ステータスの更新を担当します。
  • フォロワー: クライアントのリクエストを受信して​​結果をクライアントに返すため、およびリーダー選出プロセスで投票するために使用されます。
  • オブザーバー: クライアント接続を受け入れ、書き込み要求をリーダーに転送できますが、オブザーバーは投票プロセスには参加しません。システムを拡張し、読み取り速度を向上させるためにのみ使用されます。

Zookeeper データ モデル

  • Linuxに似た、従来のファイルシステム仕様に従って命名された階層ディレクトリ構造
  • Zookeeper 内の各ノードは znode と呼ばれ、一意のパス識別子を持ちます。
  • ノードZnodeにはデータと子ノードを含めることができますが、EPHEMERALタイプのノードには子ノードを含めることはできません。
  • Znode 内のデータには複数のバージョンが存在する場合があります。たとえば、特定のパスの下に複数のデータ バージョンがある場合、このパスの下のデータを照会するにはバージョン番号が必要です。
  • クライアントアプリケーションはノード上にモニターを設定できます
  • ノードは部分的な読み取りと書き込みをサポートしていませんが、1回限りの完全な読み取りと書き込みをサポートしています。

ZooKeeper ノードの機能

ZooKeeper ノードにはライフサイクルがあり、ノードの種類によって異なります。 ZooKeeper では、ノードは存続期間に応じて永続ノード (PERSISTENT) と一時ノード (EPHEMERAL) に分けられ、順序付けの有無に応じて順次ノード (SEQUENTIAL) と順序なしノード (デフォルトでは順序なし) に分けられます。

永続ノードが作成されると、削除されない限り Zookeeper に残ります (ノードを作成したクライアントのセッションが無効になっても消えることはありません)。

Zookeeperの応用シナリオ

ZooKeeper は、可用性の高い分散データ管理およびシステム調整フレームワークです。このフレームワークは、Paxos アルゴリズムの実装に基づいて、分散環境におけるデータの強力な一貫性を保証します。また、この機能に基づいて、ZooKeeper は多くの分散問題を解決できます。

ZooKeeper はこれらのアプリケーション シナリオ向けに設計されたものではないことに注意してください。代わりに、多くの開発者が後に、フレームワークの特性と、フレームワークが提供する一連の API インターフェイス (またはプリミティブ セット) に基づいて、一般的な使用方法を模索しました。

データの公開とサブスクリプション(構成センター)

パブリッシュ アンド サブスクライブ モデル (構成センターとも呼ばれます) は、パブリッシャーが ZK ノードにデータを公開し、サブスクライバーがデータを動的に取得できるようにすることで、構成情報の集中管理と動的な更新を実現することを意味します。たとえば、グローバル構成情報、サービスベースのサービス フレームワークのサービス アドレス リストなどは、使用に非常に適しています。

アプリケーションで使用される一部の構成情報は、集中管理のために ZK に配置されます。このタイプのシナリオは通常、次のようになります。アプリケーションは起動時に構成を一度アクティブに取得し、同時にノードにウォッチャーを登録します。このようにして、構成が更新されるたびに、サブスクライブされたクライアントにリアルタイムで通知され、最新の構成情報を取得するという目的が達成されます。 分散検索サービスでは、サーバー クラスター マシンのインデックス メタデータとノード ステータスが、さまざまなクライアントによるサブスクリプションのために ZK の指定されたノードに保存されます。 分散ログ収集システム。このシステムの中心的な仕事は、異なるマシンに分散されたログを収集することです。コレクターは通常、アプリケーションに応じて収集タスク単位を割り当てます。そのため、アプリケーション名をパスとして ZK 上にノード P を作成し、このアプリケーションのすべてのマシン IP をノード P 上の子ノードとして登録する必要があります。このようにして、マシンが変更された場合、コレクターにリアルタイムで通知して、タスク割り当てを調整できます。 システム内の一部の情報は動的に取得する必要があり、この情報を手動で変更するという問題もあります。通常、ランタイム情報を取得するために、JMX インターフェースなどのインターフェースが公開されます。 ZK を導入すると、自分でソリューションを実装する必要がなくなり、指定された ZK ノードにこの情報を保存するだけで済みます。 注: 上記のアプリケーション シナリオには、データ量は少ないが、データの更新は比較的高速であるというデフォルトの前提があります。

負荷分散

ここで言う負荷分散とは、ソフト負荷分散を指します。分散環境では、高可用性を確保するために、同じアプリケーションまたはサービスのプロバイダーは通常、複数のコピーを展開してピアツーピア サービスを実現します。コンシューマーは、関連するビジネス ロジックを実行するためにこれらのピア サーバーの 1 つを選択する必要があります。その中で最も典型的なのは、メッセージ ミドルウェアにおけるプロデューサーとコンシューマーの負荷分散です。

ネーミングサービス

ネーミング サービスは分散システムでは一般的なシナリオでもあります。分散システムでは、ネーミング サービスを使用することで、クライアント アプリケーションは指定された名前に基づいて、リソースまたはサービスのアドレス、プロバイダー、およびその他の情報を取得できます。名前付きエンティティは通常、クラスター内のマシン、提供されるサービス アドレス、リモート オブジェクトなどであり、これらをまとめて名前と呼ぶことができます。その中で、より一般的なのは、一部の分散サービス フレームワークのサービス アドレス リストです。 ZK が提供するノード作成 API を呼び出すことで、名前として使用できるグローバルに一意のパスを簡単に作成できます。

Alibaba Group のオープンソース分散サービス フレームワーク Dubbo は、グローバル サービス アドレス リストを維持するために、命名サービスとして ZooKeeper を使用します。 Dubbo 実装の場合: サービス プロバイダーが起動すると、その URL アドレスが ZK 上の指定されたノード/dubbo/${serviceName}/providersディレクトリに書き込まれます。この操作により、サービスのリリースが完了します。 サービス コンシューマーが起動すると、 /dubbo/${serviceName}/providersディレクトリ内のプロバイダー URL アドレスをサブスクライブし、独自の URL アドレスを/dubbo/${serviceName} /consumersディレクトリに書き込みます。 ZK に登録されているすべてのアドレスは一時ノードであるため、サービス プロバイダーとコンシューマーはリソースの変更を自動的に検出できることに注意してください。

さらに、Dubbo は、 /dubbo/${serviceName}ディレクトリ内のすべてのプロバイダーとコンシューマーの情報にサブスクライブすることで、サービス レベルの監視も提供します。

分散通知/調整

ZooKeeper 独自のウォッチャー登録と非同期通知メカニズムにより、分散環境における異なるシステム間の通知と調整を効果的に実装し、データ変更のリアルタイム処理を実現できます。使用方法としては、通常、異なるシステムが ZK に同じ znode を登録し、znode の変更 (znode 自体とその子ノードの内容を含む) を監視します。1 つのシステムが znode を更新すると、他のシステムが通知を受信して​​対応する処理を行うことができます。

別のハートビート検出メカニズム: 検出システムと検出されたシステムは直接リンクされていませんが、zk 上のノードを介してリンクされているため、システムの結合が大幅に削減されます。 別のシステム スケジューリング モード: システムは、コンソールとプッシュ システムの 2 つの部分で構成されます。コンソールは、プッシュ システムを制御して対応するプッシュ作業を実行する役割を担います。コンソールでマネージャーが実行する一部の操作は、実際に ZK 上の特定のノードのステータスを変更し、ZK はウォッチャーを登録しているクライアント、つまりプッシュ システムにこれらの変更を通知し、対応するプッシュ タスクを実行します。

別の作業報告モード: タスク分散システムに似ていますが、サブタスクが開始されると、zk に移動して一時ノードを登録し、定期的に進行状況を報告します (進行状況をこの一時ノードに書き戻します)。これにより、タスク マネージャーはタスクの進行状況をリアルタイムで知ることができます。

分散ロック

分散ロックは主に、ZooKeeper によって保証されるデータの強力な一貫性によるものです。ロック サービスは、排他性を維持するためのものと、タイミングを制御するためのものの 2 つのカテゴリに分けられます。

いわゆる排他的所有権とは、ロックを取得しようとしているすべてのクライアントのうち、1 つのクライアントだけがロックを正常に取得できることを意味します。通常の方法は、 zk 上の znode をロックと見なし、 create znodeてそれを実装することです。すべてのクライアントは/distribute_lockノードを作成し、ノードを正常に作成したクライアントがロックを所有します。 タイミングを制御するということは、ロックを取得しようとするすべてのクライアントが最終的に実行するようにスケジュールされることを意味しますが、グローバルなタイミングが存在します。このアプローチは上記と似ていますが、 /distribute_lockすでに存在し、クライアントがその下に一時的に順序付けられたノードを作成する点が異なります (これはノードのプロパティによって制御できます: CreateMode.EPHEMERAL_SEQUENTIALを指定します)。 Zk の親ノード ( /distribute_lock ) は、子ノードの作成タイミングを保証するためのシーケンスを維持し、それによって各クライアントのグローバル タイミングを形成します。

同じノード下のサブノードの名前は同じにすることはできないため、特定のノード下に znode が作成されている限り、作成が成功するとロックが成功したことを意味します。この znode を監視するリスナーを登録し、この znode が削除されるとすぐに他のクライアントにロックするように通知します。一時的なシーケンシャルノードの作成: あるノードの下にノードを作成します。リクエストが来るとノードが作成されます。シーケンシャルなので、シーケンス番号が最も小さいものがロックを取得します。ロックが解除されると、次のシーケンス番号にロックを取得するように通知されます。

分散キュー

キューには、簡単に言えば 2 つの種類があります。1 つは通常の先入れ先出しキューで、もう 1 つはキューのメンバーがすべて集まるまで待ってから順番に実行するキューです。最初のタイプのキューの基本原理は、前述の分散ロック サービスのタイミング制御シナリオと同じなので、ここでは詳細には説明しません。

2 番目のタイプのキューは、実際には FIFO キューに基づいた拡張機能です。通常、 /queue znode の下に/queue/numノードを事前に作成し、キューのサイズを示すために n の値を割り当てる (または /queue に n を直接割り当てる) ことができます。その後、キュー メンバーが参加するたびに、キューのサイズに達したかどうかが判断され、実行を開始できるかどうかが決定されます。この使用法の典型的なシナリオは、分散環境で、大規模なタスク (タスク A) は、多くのサブタスクが完了した後 (または条件が準備された後) にのみ実行できるというものです。このとき、サブタスクの 1 つが完了 (準備完了) するたびに、 /taskListの下に独自の一時シーケンス ノード ( CreateMode.EPHEMERAL_SEQUENTIAL ) が作成されます。 /taskListは、その下の子ノードの数が指定された数を満たしていることを検出すると、次のステップに進み、順番に処理することができます。

dokcer-compose を使用してクラスターを構築する

これまで、ZooKeeper のさまざまな応用シナリオを紹介してきました。次に、まず ZooKeeper クラスターの構築方法を学習し、上記の応用シナリオを実践します。

ファイルのディレクトリ構造は次のとおりです。

├── docker-compose.yml

docker-compose.ymlファイルを書き込む

docker-compose.ymlファイルの内容は次のとおりです。

バージョン: '3.4'
サービス:
 動物園1:
 画像: 動物園の飼育係
 再起動: 常に
 ホスト名: zoo1
 ポート:
  - 2181:2181
 環境:
  動物園ID: 1
  ZOO_SERVERS: server.1=0.0.0.0:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
 動物園2:
 画像: 動物園の飼育係
 再起動: 常に
 ホスト名: zoo2
 ポート:
  - 2182:2181
 環境:
  動物園_マイ_ID: 2
  ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=0.0.0.0:2888:3888;2181 server.3=zoo3:2888:3888;2181
 動物園3:
 画像: 動物園の飼育係
 再起動: 常に
 ホスト名: zoo3
 ポート:
  - 2183:2181
 環境:
  動物園ID: 3
  ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=0.0.0.0:2888:3888;2181

この構成ファイルでは、Docker は 3 つの Zookeeper イメージを実行し、ports フィールドを通じてローカル ポート 2181、2182、および 2183 を対応するコンテナーのポート 2181 にバインドします。

ZOO_MY_IDZOO_SERVERS 、Zookeeper クラスターを構築するために必要な 2 つの環境変数です。 ZOO_MY_IDサービス ID を識別します。これは 1 ~ 255 の整数であり、クラスター内で一意である必要があります。 ZOO_SERVERSクラスター内のホストのリストです。

起動ログを表示するには、 docker-compose.ymlが配置されているディレクトリでdocker-compose up実行します。

ZooKeeperへの接続

クラスターを起動したら、ZooKeeper に接続してノード関連の操作を実行できます。

まず、ZooKeeper をダウンロードする必要があります。 ZooKeeper のダウンロード アドレス。それをconfディレクトリに解凍し、 zoo_sample .cfg zoo.cfg変更します。

設定ファイルの説明

# 各ティックのミリ秒数
# tickTime: CS 通信ハートビート番号 # Zookeeper サーバー間またはクライアントとサーバー間のハートビートを維持するための時間間隔。つまり、ハートビートは tickTime ごとに送信されます。 tickTime はミリ秒単位です。
ティックタイム=2000

# 初期値であるティック数
# 同期フェーズは
# initLimit: LF 初期通信時間制限 # クラスター内のフォロワー サーバー (F) とリーダー サーバー (L) 間の初期接続中に許容できるハートビートの最大数 (tickTime の数)。
初期化制限=5

# 通過できるティック数
# リクエストを送信し、確認応答を受け取る
# syncLimit: LF 同期通信時間制限 # クラスター内のフォロワー サーバーとリーダー サーバー間の要求と応答間で許容できるハートビートの最大数 (tickTime の数)。
同期制限=2

# スナップショットが保存されるディレクトリ。
# /tmpをストレージとして使用しないでください。ここでの/tmpは
# 例のため。
# dataDir: データ ファイル ディレクトリ #Zookeeper がデータを保存するディレクトリ。デフォルトでは、Zookeeper はデータの書き込みに関するログ ファイルもこのディレクトリに保存します。
データディレクトリ=/data/soft/zookeeper-3.4.12/data


# dataLogDir: ログ ファイル ディレクトリ # Zookeeper がログ ファイルを保存するディレクトリ。
データログディレクトリ=/data/soft/zookeeper-3.4.12/logs

# クライアントが接続するポート
# clientPort: クライアント接続ポート# クライアントが Zookeeper サーバーに接続するために使用するポート。Zookeeper はこのポートをリッスンし、クライアントからのアクセス要求を受け入れます。
クライアントポート=2181

# クライアント接続の最大数。
# より多くのクライアントを処理する必要がある場合は、これを増やします
#最大クライアント接続数=60
#
# 必ずメンテナンスセクションをお読みください
# 自動消去をオンにする前に管理者ガイドを参照してください。
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# dataDir に保持するスナップショットの数
#自動パージ.スナップ保持カウント=3
# 消去タスク間隔(時間単位)
# 自動パージ機能を無効にするには「0」に設定します
#自動パージ.パージ間隔=1


# サーバー名とアドレス: クラスター情報 (サーバー番号、サーバーアドレス、LF 通信ポート、選択ポート)
# この設定項目の記述形式は特殊で、ルールは次のとおりです。

# サーバー.N=YYY:A:B

# ここで、N はサーバー番号、YYY はサーバー IP アドレス、A は LF 通信ポートであり、クラスター内のサーバーとリーダー間の情報交換用のポートを示します。 B は選出ポートであり、新しいリーダーを選出するときにサーバーが相互に通信するポートを示します (リーダーが失敗すると、残りのサーバーが相互に通信して新しいリーダーを選択します)。一般的に、クラスター内の各サーバーの A ポートは同じであり、各サーバーの B ポートも同じです。ただし、疑似クラスターを使用する場合、IP アドレスは同じで、A ポートと B ポートのみが異なります。

zoo.cfg を変更する必要はありません。デフォルトの設定で問題ありません。次に、解凍​​した bin ディレクトリでコマンド./zkCli.sh -server 127.0.0.1:2181実行して接続します。

ZooKeeper へようこそ!
2020-06-01 15:03:52,512 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@1025] - サーバー localhost/127.0.0.1:2181 へのソケット接続を開いています。SASL を使用して認証を試行しません (不明なエラー)
JLineサポートが有効になっています
2020-06-01 15:03:52,576 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@879] - localhost/127.0.0.1:2181 へのソケット接続が確立され、セッションが開始されました
2020-06-01 15:03:52,599 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@1299] - サーバー localhost/127.0.0.1:2181 でセッションの確立が完了しました。セッション ID = 0x100001140080000、ネゴシエートされたタイムアウト = 30000

ウォッチャー::

WatchedEvent 状態:SyncConnected タイプ:None パス:null
[zk: 127.0.0.1:2181(接続済み) 0]

次に、コマンドを使用してノードを表示します。

現在のZooKeeperの内容を表示するには、lsコマンドを使用します。

コマンド: ls /

[zk: 127.0.0.1:2181(接続済み) 10] ls /

[飼育係] ```

新しい znode「zk」が作成され、それに文字列が関連付けられます。

コマンド: create /zk myData

[zk: 127.0.0.1:2181(接続済み) 11] /zk myData を作成

/zk を作成しました [zk: 127.0.0.1:2181(CONNECTED) 12] ls / [zk, zookeeper] [zk: 127.0.0.1:2181(CONNECTED) 13] ```

znode ノードzkを取得

コマンド: get /zk

[zk: 127.0.0.1:2181(接続済み) 13] /zk を取得

myData cZxid = 0x400000008 ctime = 2020年6月1日月曜日15:07:50 CST mZxid = 0x400000008 mtime = 2020年6月1日月曜日15:07:50 CST pZxid = 0x400000008 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 6 numChildren = 0

```

znodeノードzkを削除する

コマンド: delete /zk

[zk: 127.0.0.1:2181(接続済み) 14] /zk を削除

[zk: 127.0.0.1:2181(接続済み) 15] ls / [zookeeper] ```

スペースが限られているため、次の記事では、上記の ZooKeeper アプリケーション シナリオをコードで 1 つずつ実装します。

ZooKeeper の Docker 設定ファイルを保存する場所

ZooKeeper の Docker 設定ファイルを保存する場所

ZooKeeper の Docker 設定ファイルを保存する場所

上記のプロジェクトを直接プルできます。RocketMQ を起動するには 2 つの手順だけが必要です。

GitHub からプロジェクトをプルし、ZooKeeper フォルダーでdocker-compose upコマンドを実行します。

参考文献

http://www.jucaiylzc.cn /2011/10/08/1232/
http://www.dongdongrji.cn /2019/04/25/1_Zookeeper%E8%AF%A6%E8%A7%A3/
https://www.jintianxuesha.com/cyfonly/p/5626532.html
http://www.hengxuangyul.com .com/docker-zookeeper-cluster/
https://www.qiaoheibpt.com maizitoday.github.io/post/zookeeper%E5%85%A5%E9%97%A8/

要約する

史上最も便利なZookeeperサーバー構築方法についての記事はこれで終わりです。Zookeeperサーバー構築に関するより関連性の高いコンテンツについては、123WORDPRESS.COMの過去の記事を検索するか、以下の関連記事を引き続き閲覧してください。今後とも123WORDPRESS.COMをよろしくお願いいたします。

以下もご興味があるかもしれません:
  • ZooKeeperの動作原理の簡単な分析
  • Java ZooKeeper 分散ロック実装図
  • Zookeeper に基づく分散ロックの詳細な説明
  • ZooKeeper 分散調整サービス設計のコアコンセプトとインストール構成

<<:  jsプロジェクトでの双方向データバインディングの簡単な実装方法

>>:  mysql MGR シングルマスターとマルチマスターモードの切り替えの知識ポイントの詳細な説明

推薦する

CSSとJSでロマンチックな流星群アニメーションを実現

1. レンダリング 2. ソースコードhtml < 本文 > < div クラス ...

MySQL 5.7を完全にアンインストールするための詳細な手順

この記事は主に、MySQLを再インストールする際のクリーンでないアンインストールのさまざまな問題をま...

MySQL 5.7.20 Green Edition のインストールの詳細なグラフィックチュートリアル

まず、MySQL とは何かを理解しましょう。 MySQL は、スウェーデンの会社 MySQL AB ...

間違った MySQL コマンドをキャンセルしたい場合はどうすればいいですか?

間違った mysql コマンドを入力したのでキャンセルしたいです。どうすればいいですか? ctrl ...

MySQL UPDATE ステートメントの非標準実装コード

今日は、MySQL データベースと SQL 標準 (および他のデータベース) の UPDATE ステ...

Vue3 の ref と toRef の違いを簡単に分析します

1. refがコピーされ、ビューが更新されますrefを使用してオブジェクトのプロパティ値をレスポンシ...

Reactにおけるフックの一般的な使用法

目次1. フックとは何ですか? 2. フックはなぜ現れるのでしょうか? 3. よく使われるフックは何...

Linx awk入門チュートリアルの詳細な説明

Awk はテキスト ファイルを処理するためのアプリケーションであり、ほぼすべての Linux システ...

Mysqlは日付範囲の抽出方法を指定します

データベースを操作する過程では、いくつかの指標を日付別にまとめたり、一定期間内の合計金額をカウントし...

Dockerイメージを素早くデプロイして実行する最新のIDEAプロセスの詳細な説明

背景docker とアイデアを使用して、Java Web の開発、展開、運用までのプロセス全体を実現...

MySQL 5.7.18 無料インストール版ウィンドウ設定方法

初めてのブログです。データベースの勉強を始めた頃のことを書いています。自分でダウンロードしたのですが...

新しいカーネルをLinuxシステムに移植する手順

1. ubuntu16.04 イメージと対応する ubuntu16.04 カーネル バージョンのソー...

Docker コンテナは実行後に終了します (実行を継続する方法)

現象Dockerコンテナを起動する docker run –name [コンテナ名] [コンテナID...

Vue.jsはコンポーネントを通じてアイコンを処理します

アイコン処理ソリューションこの記録の目的は、element-plus 以外のアイコンをコンポーネント...

デザインにおけるユーザーエクスペリエンスの背後にある8つのユーザー本能について話す

編集者注: この記事は、Teambition チームの @娄昊川 が寄稿したものです。Teambit...