Zookeeperの8つの典型的なアプリケーションシナリオについて何を知っていますか?

オタクタイムはまた新しいです、それは実際に有名なzkであり、そこで講師はzkの使用シーンを紹介しました。著者は、zkの3つの有名な使用シナリオについてのみ言及しましたが、実際、多くの人が使用しない可能性のある他の5つの使用シナリオがあり、著者はそれらを紹介しませんでした。それでは、今日はすべてをまとめましょう!

Zookeeperの8つの典型的なアプリケーションシナリオについて何を知っていますか?

動物園の飼育係の紹介

ZooKeeperは、分散型のオープンソース分散型アプリケーション調整サービスであり、GoogleのChubbyのオープンソース実装であり、HadoopとHbaseの重要なコンポーネントです。分散アプリケーションに一貫したサービスを提供するソフトウェアです。提供される機能には、構成の保守、ドメイン名サービス、分散同期、グループサービスなどがあります。

ZooKeeperの目標は、複雑でエラーが発生しやすい主要なサービスをカプセル化し、ユーザーにシンプルで使いやすいインターフェイスと、高性能で安定した機能を備えたシステムを提供することです。

ZooKeeperには、JavaとCの間のインターフェースを提供するプリミティブの単純なセットが含まれています。

ZooKeeperコードバージョンは、分散排他ロック、選択、およびキューのインターフェイスを提供します。コードはzookeeper-3.4.3 \ src \ recipesにあります。その中で、分散ロックとキューにはJavaとCの2つのバージョンがあり、選出にはJavaバージョンしかありません。

Zookeeperは、高可用性、高性能、分散データの整合性を備えた分散データ管理および調整フレームワークです。ZABアルゴリズムの実装に基づいています。この機能に基づいて、zkは分散整合性の問題を解決するための強力なツールになります。 、Zookeeperは、豊富なノードタイプとWatcher監視メカニズムを提供します。これらの2つの機能により、分散システムに関連する一連のコア機能を構築するのに非常に便利です。データの公開/サブスクリプション、負荷分散、ネーミングサービス、配布調整/通知、クラスター管理、マスター選択、分散ロック、分散キューなど。

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

データ公開/サブスクリプションシステムは、構成センターとも呼ばれます。パブリッシャーは、サブスクライバーがデータをサブスクライブするために、Zookeeperノードにデータを公開する必要があります。これにより、データを動的に取得し、構成情報の集中管理とデータの動的更新を実現します(RPCレジストリはアプリケーションと見なすことができます)。このシナリオの)。

パブリッシュ/サブスクライブには通常、プッシュモードとプルモードの2つの設計モードがあります。サーバーはプッシュモードと呼ばれるサブスクライブされたすべてのクライアントにデータ更新をアクティブに送信します。クライアントはプルモードと呼ばれ、最新のデータをアクティブに要求します。Zookeeperはプッシュとプルを使用します。複合モードの場合、クライアントは注意が必要なノードをサーバーに登録します。ノードデータが変更されると、サーバーはWatcherイベント通知を対応するクライアントにプッシュします。クライアントがこの通知を受信すると、次のことを主導します。サービス。最後に最新のデータを取得します。

構成情報が集中管理のためにZookeeperに保存されている場合、通常の状況では、アプリケーションは起動時にZookeeperサーバーの構成情報を取得すると同時に、指定されたノードにウォッチャーを登録して監視します。構成情報。変更が発生すると、サーバーは、最新の構成をリアルタイムで取得するという目的を達成するために、サブスクライブされたすべてのクライアントにリアルタイムで通知します。

注:DubboなどのRPCフレームワークの場合、zkは登録センターとして機能します。クライアントはzkクラスターからサービスのアドレスを初めて取得し、ローカルに保存します。次に呼び出されると、再度zkに移動しないでください。クラスター内のクエリは、ローカルに保存されたアドレスを直接使用し、サービスアドレスが変更された場合にのみ、クライアントに再度取得するように通知されます。

通常の開発では、このような要件に遭遇することがよくあります。マシンリスト情報、データベース構成情報(たとえば、データベース切り替えを実現するためのアプリケーションシナリオ)、ランタイムスイッチ構成など、いくつかの一般的な構成情報をシステムで使用する必要があります。 。これらのグローバル構成情報には通常、3つの特性があります。データの量は通常比較的少ない、データの内容は操作中に動的に変化する、クラスター内のマシンは共有され、同じように構成されます。クラスタが非常に大きく、構成情報が頻繁に変更されると仮定すると、ローカル構成ファイルまたはメモリ変数を格納することは困難であるため、zkを使用してグローバル構成情報を管理します。

負荷分散

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

メッセージミドルウェアのパブリッシャーとサブスクライバーの負荷分散、LinkedInのオープンソースKafkaMQ、Aliのオープンソースmetaqはすべて、zookeeperを使用してプロデューサーとコンシューマーの負荷分散を実現します。metaqの例を次に示します。プロデューサーの負荷分散:metaqがメッセージを送信する場合、プロデューサーはメッセージの送信時にメッセージを送信するブローカー上のパーティションを選択する必要があります。これにより、metaqは操作プロセス中にすべてのブローカーを送信します。対応するパーティション情報はすべてZKの指定されたノードに登録されます。デフォルトの戦略は順次ポーリングプロセスです。プロデューサーがZKを介してパーティションリストを取得すると、brokerIdとpartitionの順序でパーティションリストに編成されます。送信するときは、最初から最後まで周期的にメッセージを送信するパーティションを選択してください。消費者の負荷分散:

消費プロセス中、コンシューマーは1つ以上のパーティションでメッセージを消費しますが、パーティションは1人のコンシューマーによってのみ消費されます。MetaQの消費戦略は次のとおりです。

各パーティションは、同じグループに対して1つのコンシューマーのみをマウントします。同じグループ内のコンシューマーの数がパーティションの数よりも多い場合、追加のコンシューマーは消費に参加しません。

同じグループ内のコンシューマーの数がパーティションの数より少ない場合、一部のコンシューマーは追加のコンシューマータスクを実行する必要があります。

コンシューマーに障害が発生したり再起動したりした場合、他のコンシューマーはこの変更を認識し(zookeeper監視コンシューマーリストを介して)、負荷を再分散して、すべてのパーティションにコンシューマーが消費されるようにします。

ネーミングサービス

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

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

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

分散調整/通知

Zookeeperの独自のWatcherは、非同期通知メカニズムに登録されています。これにより、分散環境内の異なるマシン間、さらには異なるシステム間の調整と通知を十分に実現し、データ変更のリアルタイム処理を実現できます。通常は、異なるクライアントがZookeeperの同じデータノードにWatcherを登録し、データノード(ノード自体と子ノードを含む)の変更を監視します。データノードが変更されると、サブスクライブされたすべてのクライアントが対応するWatcher通知を受信できます。それに応じて対処します。

ほとんどの分散システムでは、システムマシン間の通信は、ハートビートの検出、作業の進行状況のレポート、およびシステムのスケジューリングにすぎません。これらの3種類の機械通信方法はすべて、zookeeperを使用して実装できます。

1.ハートビート検出。異なるマシンは、互いに正常に動作しているかどうかを検出する必要があります。Zookeeperを使用して、マシン間のハートビート検出を実現できます。一時ノードの特性に基づいて(一時ノードのライフサイクルはクライアントセッションです。一時ノードは当然です。異なるマシンがZookeeperの指定されたノードの下に一時的な子ノードを作成できるようにし、異なるマシンがこの一時的な子ノードに基づいて対応するクライアントマシンが稼働しているかどうかを判断できるようにします。Zookeeperを使用すると、システムの結合を大幅に減らすことができます。

2.作業進捗レポート。通常、タスクが異なるマシンに配布された後、タスクの実行進捗をリアルタイムで配布システムに報告する必要があります。Zookeeperでノードを選択すると、各タスククライアントがこのノードの下に一時的な子を作成します。このようにして、マシンが稼働しているかどうかを判断できるだけでなく、各マシンがタスク実行の進行状況を一時ノードに書き込むことができるため、中央システムはタスク実行の進行状況をリアルタイムで取得できます。

3.システムスケジューリング、Zookeeperは、次のシステムスケジューリングモードを実装できます。分散システムは、コンソールといくつかのクライアントシステムで構成されます。コンソールの責任は、すべてのクライアントにコマンド情報を送信して、それに応じて応答するように制御することです。のビジネスロジックでは、バックグラウンドマネージャーがコンソールでいくつかの操作を実行します。これは、実際にはZookeeperの一部のノードのデータを変更することです。Zookeeperは、時間通知の形式でサブスクリプションクライアントにデータ変更を送信できます。

クラスター管理

Zookeeperの2つの主要な機能(ノード機能とウォッチャーメカニズム):

1.クライアントがWatcherを登録してZookeeperのデータノードを監視している場合、注文のデータとコンテンツまたはその子ノードリストが変更されると、Zookeeperサーバーはサブスクライブされたクライアントに変更通知を送信します。

2. Zookeeperで作成された一時ノードの場合、クライアントとサーバー間のセッションが失敗すると、一時ノードも自動的に削除されます。

マシンのオンラインレートの要件が高いシナリオは、クラスター内のマシンの変更に迅速に対応できます。このようなシナリオでは、クラスターマシンがリアルタイムで稼働しているかどうかを検出する監視システムがよくあります。過去の通常の慣行は、監視システムが何らかの手段(pingなど)を介して各マシンを定期的に検出するか、各マシンが定期的に「私はまだ生きている」と監視システムに報告することです。このアプローチは実行可能ですが、2つの明らかな問題があります。

  1. クラスター内のマシンが変更されると、変更にはさらに多くのことが関係します。

  2. 多少の遅れがあります。

ZooKeeperの2つの機能により、別のクラスターマシンの存続可能性監視システムをリアルタイムで使用できます。クラスターマシンのサバイバルモニタリングシステムを実装できます。モニタリングシステムが/ clusterServersノードにウォッチャーを登録すると、マシンが動的に追加されるたびに、/ clusterServersノードの下に一時ノードが作成されます。/clusterServers/[ホスト名]、そのため、監視システムは機械の変化をリアルタイムで監視できます。

分散ログ収集システムの一般的なアプリケーションを通じて、Zookeeperがクラスター管理を実装する方法を学びましょう。

分散ログ収集システムの中心的な作業は、さまざまなマシンに分散されたシステムログを収集することです。一般的なログシステムアーキテクチャの設計では、ログシステム全体が、収集する必要のあるすべてのログマシンを複数のグループに分割し、各グループはコレクターに対応します。 、このコレクターは実際にはログを収集するためのバックグラウンドマシンです。大規模な分散ログ収集システムのシナリオでは、通常、次の2つの問題を解決する必要があります。

1.変更のログソースマシン

2.交換コレクターマシン

ログソースマシンまたはコレクターマシンの変更であるかどうかにかかわらず、最終的には、対応するログソースマシンを各コレクターに迅速、合理的、動的に割り当てる方法に起因する可能性があります。

a。コレクターマシンを登録し、/ logs / collectorのコレクターノードなど、コレクターのルートノードとしてZookeeperにノードを作成します。各コレクターマシンが起動すると、コレクターノードの下に次のような独自のノードが作成されます。 / logs / collector / [ホスト名]

Zookeeperの8つの典型的なアプリケーションシナリオについて何を知っていますか?

b。タスクの分散:すべてのコレクターマシンが対応するノードを作成した後、システムはすべてのログソースマシンをコレクターノードの下の子ノードの数に従って対応するグループに分割し、グループ化されたマシンリストをこれらのコレクションに書き込みます。 / logs / collector / host1(永続ノード)など、サーバーによって作成された子ノード。このようにして、コレクターマシンは、対応するコレクターノードに基づいてログソースマシンリストを取得し、ログ収集作業を開始できます。

c。ステータスレポート。タスクの分散が完了すると、マシンはいつでもダウンするため、コレクターのステータスレポートメカニズムが必要です。各コレクターマシンでノードが作成された後、ステータスの子ノードは次のことを行う必要があります。 / logs / collector / host / status(一時ノード)などの対応する子ノードで作成されます。各コレクターマシンは、ノードに独自のステータス情報を定期的に書き込む必要があります。これは、通常、ハートビート検出メカニズムと見なすことができます。コレクターマシンはログ収集ステータス情報を書き込みます。ログシステムは、ステータス子ノードの最終更新時刻を判断することにより、コレクターマシンが稼働しているかどうかを判断します。

d。動的割り当て。コレクターマシンがダウンしている場合は、収集タスクを動的に割り当てる必要があります。収集システムの操作中は、/ logs / collectorノードの下のすべてのサブノードの変更に注意してください。レポートを停止するか、新しいマシンが参加し、タスクの再配布を開始します。現時点では、通常、次の2つの方法があります。

1.グローバル動的割り当て。コレクターマシンがダウンするか、新しいマシンが追加されると、システムは新しいコレクターマシンリストに従ってすべてのログソースマシンをすぐに再グループ化し、残りのコレクターマシンに割り当てます。

2.ローカル動的割り当て。各コレクターマシンは、ログ収集ステータスを報告しながら、独自の負荷を報告します。マシンがダウンした場合、ログシステムは、このマシンに以前に割り当てられたタスクを再割り当てします。負荷の低いマシンに割り当てます。同様に、新しいマシンが追加されると、タスクの一部が高負荷のマシンから新しいマシンに転送されます。

マスター選挙

分散システムでは、マスターはクラスター内の他のシステムユニットを調整するためによく使用され、分散システムの状態の変化を決定する権利があります。たとえば、読み取りと書き込みが分離されているアプリケーションシナリオでは、クライアントの書き込み要求は、多くの場合、マスターによって処理されます。または、多くの場合、複雑なロジックを処理し、処理結果を他のシステムユニットに同期します。Zookeeperの整合性を使用すると、分散型の高い同時実行性の場合にノードを作成することで、グローバルな一意性が確保されます。つまり、Zookeeperは、クライアントが既存のデータノードを繰り返し作成できないようにします(分散型データの整合性保証による)。 )。

最初に/ master_election / 2016-11-12ノードを作成します。クライアントクラスターは、このノードの下に/ master_election / 2016-11-12 / bindingなどの一時ノードを毎日定期的に作成します。このプロセスでは、1つのクライアントのみを作成できます。この時点で、それはマスターになり、他のノードはノード/ master_election / 2016-11-12に子ノードの変更のウォッチャーを登録します。これは、現在のマスターマシンが稼働しているかどうかを監視するために使用されます。マスターがダウンしていることが判明した場合、残りのクライアントはマスター選挙が再び開催されます。

さらに、このシナリオの進化は動的なマスター選挙です。これは、EPHEMERAL_SEQUENTIALタイプのノードの特性を使用します。

上記のように、すべてのクライアント作成要求のうち、最終的に正常に作成できるのは1つだけです。ここで少し変更を加えると、すべてのリクエストを正常に作成できるようになりますが、作成順序が必要であるため、すべてのリクエストが最終的にZKで結果を作成する可能性のある状況は次のとおりです。/currentMaster/{sessionId}-1 、?/ currentMaster / {sessionId} -2、?/ currentMaster / {sessionId} -3…..シリアル番号が最も小さいマシンがマスターとして選択されるたびに、このマシンがハングアップすると、彼が作成したノードは次のようになります。毎時すぐに、その後最小のマシンはマスターです。

その実用的なアプリケーションは次のとおりです。

検索システムでは、クラスター内の各マシンが完全なインデックスを生成する場合、時間がかかるだけでなく、インデックスデータが相互に整合していることを保証できません。したがって、クラスター内のマスターに完全なインデックスを生成させてから、クラスター内の他のマシンと同期させます。また、マスター選出の災害復旧対策として、いつでも手動でマスターを指定できます。つまり、zkがマスター情報を取得できない場合は、httpなどを介して場所からマスターを取得できます。

Hbaseでは、ZooKeeperは動的なHMaster選択を実装するためにも使用されます。Hbaseの実装では、一部のROOTテーブルのアドレスとHMasterのアドレスがZKに格納されます。また、HRegionServerは一時ノード(エフェメラル)の形式でZookeeperに登録されるため、HMasterはそれぞれの存続ステータスを検知できます。 HRegionServerはいつでも。同時に、HMasterに問題が発生すると、HMasterが再選出されて実行されるため、HMasterの問題の単一ポイントを回避できます。

分散ロック

分散ロック。これは主に、ZooKeeperが強力なデータ整合性を保証しているためです。ロックサービスは2つのカテゴリに分類できます。1つは排他的であり、もう1つはタイミングを制御することです。

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

分散キュー

キューに関しては、単純に2つのタイプがあります。1つは通常の先入れ先出しキューで、もう1つはキューメンバーが収集されるまで待ってから順番に実行されます。最初の先入れ先出しキューの場合、分散ロックサービスの制御シーケンスシナリオの基本原則は同じであるため、ここでは繰り返しません。

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

おすすめ

転載: blog.51cto.com/15127565/2664956