導入
Java アプリケーションにはさまざまな構成があることがよくあります。たとえば、アドレスや接続ポートなどです。たとえば、
Propertiesクラスを使用すると次のようになります。
public static void main(String []args) {
Properties props = new Properties();
props.setProperty("host", "www.tutorialspoint.com");
System.out.println("Hello, " + props.getProperty("host"));
}
これで十分なようです、なぜなら... ファイルからプロパティを取得できます。そして、すべてが 1 台のマシン上でうまく機能しているようです。しかし、私たちのシステムが、互いに分離されたさまざまなシステムで構成され始めると想像してみてください。このようなシステムは分散システムとも呼ばれます。Wikipedia には次の定義があります。
分散システムとは、コンポーネントが異なるネットワーク コンピューター上に配置され、相互に通信し、相互にメッセージを交換することで動作を調整するシステムです。次の図を見てください。
このアプローチでは、単一のシステムがコンポーネントに分割されます。構成は別の共通コンポーネントです。他の各コンポーネントは、構成コンポーネントのクライアントとして機能します。この場合を「
分散構成」と呼びます。分散構成にはさまざまな実装があります。そして今日のレビューでは、そのうちの 1 つである Zookeeper について知ることを提案します。
動物園の飼育員
Zookeeper について知るためのパスは、Zookeeper の公式 Web サイトから始まります
。zookeeper.apache.org公式 Web サイトで、「ダウンロード」 セクションに移動する必要があります。このセクションでは、アーカイブを .tar.gz 形式 (例: 「zookeeper-3.4.13.tar.gz」) でダウンロードします。tar は、ユニット システムの伝統的なアーカイブ形式です。gz - アーカイブの圧縮に gzip が使用されることを意味します。Windows マシンで作業している場合、これは気にならないはずです。最新のアーカイバー (たとえば、
7-zip ) のほとんどは、Windows 上で完全に動作します。内容をディレクトリに抽出してみましょう。同時に、違いもわかります。抽出された状態のディスクでは約 60 メガバイトを占有し、サイズが約 35 メガバイトのアーカイブをダウンロードしました。ご覧のとおり、圧縮は実際に機能します。次に、Zookeeper を起動する必要があります。一般に、Zookeeper は一種のサーバーです。
Zookeeper は、スタンドアロン モードまたは
複製モードの 2 つのモードのいずれかで実行できます。最初のオプションとも呼ばれる最も単純なオプションであるスタンドアロン モードを考えてみましょう。Zookeper を実行するには、構成ファイルが必要です。したがって、ここで作成しましょう:
[КаталогРаспаковкиZookeeper]/conf/zoo.cfg
。
Windows の場合は、Medium の推奨事項「 Windows に Apache ZooKeeper をインストールする」を使用します。設定ファイルの内容は次のようになります。
tickTime=2000
dataDir=C:/zookeeper-3.4.13/data
clientPort=2181
Zookeper のルート ディレクトリへのパスを含む ZOOKEEPER_HOME 環境変数を追加しましょう (媒体の手順と同様)。また、次のフラグメントを PATH 環境変数に追加します。
;%ZOOKEEPER_HOME%\bin;
また、dataDir で指定されたディレクトリが存在する必要があります。そうでない場合、Zookeeper は存在しません。サーバーを起動できるようになりました。これで、zkServer コマンドを使用してサーバーを安全に起動できるようになりました。Zookeeper ディレクトリが path 環境変数に追加されているため、bin ディレクトリだけでなく、どこからでも Zookeeper コマンドを呼び出すことができます。
Zノード
「 Zookeeper の概要」で述べたように、Zookeper のデータはツリー構造に編成された
ZNode (ノード)の形式で表現されます。つまり、各 ZNode にデータを含めることができ、子 ZNode を持つことができます。ZNode 組織の詳細については、Zookeeper のドキュメント「
データ モデルと階層名前空間」を参照してください。
Zookeeper と ZNode を操作するには、 Zookeeper CLI (コマンド ライン インターフェイス)を使用します。以前は、zkServer コマンドを使用してサーバーを起動しました。接続するには、実行しましょう。
zkCli.cmd -server 127.0.0.1:2181
成功すると、Zookeeper への接続セッションが作成され、次のような出力が表示されます。
興味深いことに、インストール直後であっても、Zookeeper にはすでに ZNode が含まれています。次のパスがあります。
/zookeeper/quota
これらはいわゆる「
クォータ」です。
「 Apache ZooKeeper Essentials 」で説明したように、各 ZNode にはクォータを関連付けて、保存できるデータを制限できます。znode の数と保存されるデータの量の制限を指定できます。さらに、この制限を超えた場合、ZNode での操作はキャンセルされませんが、制限を超えたことに関する警告が表示されます。
ZNode については、「 ZooKeeper プログラマーズ ガイド: ZNodes 」を読むことをお勧めします。そこから、ZNode を使用する方法の例をいくつか示します。
ZNode が異なることにも注意してください。
通常の ZNode (追加のフラグを指定しない限り) は「 persistent 」タイプです。
「エフェメラルノード」タイプの ZNode があります。このような ZNode は、ZNode が作成された Zookeeper 接続セッションの間のみ存在します。
「 Sequence Node 」タイプの ZNode があります。これらの ZNode には、一意性を確保するためにシーケンスの番号が追加されます。シーケンス ノードは永続的または一時的なものになります。ZNode に関する背景情報については、「
Zookeeper ZNodes – 特性と例」で参照することをお勧めします。
ZNode ウォッチャー
ウォッチャーについてもお話したいと思います。これらについての詳細は、Zookeeper のドキュメント「
ZooKeeper Watches」に書かれています。つまり、ウォッチャーは、何らかのイベントによってトリガーされる 1 回限りのトリガーです。getData()、getChildren()、またはexists()操作を実行してデータを取得することにより、追加のアクションとしてトリガーを作成できます。Zookeeper は、イベントが処理される順序を保証します。さらに、ドキュメントには、新しい ZNode 値を確認する前に、古い値を新しい値に変更するイベントが表示されると記載されています。
Watchers について詳しくは、「 ZooKeeper Watches – 機能と保証」をご覧ください。これを試すために、もう一度
CLIを使用してみましょう。サービスのステータスを保存する値を持つ ZNode があると仮定します。
[zk: 127.0.0.1:2181(CONNECTED) 0] create /services/service1/status stopped
Created /services/service1/status
[zk: 127.0.0.1:2181(CONNECTED) 1] get /services/service1/status [watch]
stopped
ここで、データが
/services/service1/status
変更されると、1 回限りのトリガーが起動されます。
興味深いことに、Zookeeper に接続すると、ウォッチャーがどのように動作するかも確認できます。
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
SyncConnected は、 Zookeper イベントとして考えられるものの 1 つです。詳細については、API の説明を参照してください。
動物園の飼育員とJava
これで、Zookeeper で何ができるかについての基本的な理解が深まりました。ここでは、CLI ではなく Java を使用して作業してみましょう。このためには、Zookeeper と連携する方法を説明する Java アプリケーションが必要になります。アプリケーションを作成するには、
Gradleプロジェクト ビルド システムを使用します。「
Gradle Build Init プラグイン」を使用してプロジェクトを作成します。これを行うには、次のコマンドを実行しましょう。
gradle init --type java-application
Gradle が質問を明確にするように求めた場合は、デフォルト値のままにします (Enter キーを押すだけです)。次に、ビルド スクリプトを開いてみましょう。build.gradle ファイル。これには、プロジェクトが何で構成されているか、およびプロジェクトが依存するアーティファクト (ライブラリ、フレームワーク) についての説明が含まれています。なぜなら Zookeeper を使用したい場合は、それを追加する必要があります。したがって、Zookeeper への依存関係を依存関係ブロックに追加しましょう。
dependencies {
implementation 'org.apache.zookeeper:zookeeper:3.4.13'
Gradle について詳しくは、「 Gradle の概要」 のレビューをご覧ください。Java プロジェクトがあり、それに Zookeeper ライブラリを接続しました。さあ、何か書いてみましょう。覚えているとおり、CLI を使用して次のように接続しました。
zkCli.cmd -server 127.0.0.1:2181
main メソッドの App クラスで「server」属性を宣言しましょう。
String server = "127.0.0.1:2181";
接続は即座に行われるアクションではありません。接続が行われるまで、プログラム実行のメインスレッドで何らかの方法で待機する必要があります。したがって、ロックが必要です。以下で宣言してみましょう。
Object lock = new Object();
次に、接続が確立されたことを誰かが言う必要があります。覚えているように、CLI を通じてこれを実行すると、ウォッチャーが機能しました。したがって、Java コードではすべてがまったく同じです。ウォッチャーは正常に完了したことを示すメッセージを表示し、ロックを介して待機している全員に通知します。ウォッチャーを書いてみましょう:
Watcher connectionWatcher = new Watcher() {
public void process(WatchedEvent we) {
if (we.getState() == Event.KeeperState.SyncConnected) {
System.out.println("Connected to Zookeeper in " + Thread.currentThread().getName());
synchronized (lock) {
lock.notifyAll();
}
}
}
};
次に、zooKeeper サーバーへの接続を追加しましょう。
int sessionTimeout = 2000;
ZooKeeper zooKeeper = null;
synchronized (lock) {
zooKeeper = new ZooKeeper(server, sessionTimeout, connectionWatcher);
lock.wait();
}
ここではすべてがシンプルです。プログラムのメイン スレッドで main メソッドを実行するときに、ロックを取得し、Zookeeper への接続を要求します。同時にロックを解放し、他の誰かがロックを取得して続行できることを通知するまで待ちます。接続が確立されると、ウォッチャーが動作します。彼は、SyncConnected イベントが到着したことを確認し (覚えているとおり、これはウォッチャーが CLI を通じて取得したものです)、メッセージを書き込みます。次に、ロックを取得し (メインスレッドが以前にロックを解放したため)、ロックを待機しているすべてのスレッドに続行できることを通知します。イベント処理スレッドは同期ブロックを終了し、ロックを解放します。メインスレッドは通知を受信し、ロックが解放されるのを待った後、実行を続行します。ロックを受け取るまでは、同期ブロックを抜けて作業を続けることはできません。したがって、マルチスレッドと Zookeeper API を使用して、さまざまなアクションを実行できます。Zookeeper API は、CLI で許可されているものよりもはるかに広範です。例えば:
String znodePath = "/zookeepernode2";
List<ACL> acls = ZooDefs.Ids.OPEN_ACL_UNSAFE;
if (zooKeeper.exists(znodePath, false) == null) {
zooKeeper.create(znodePath, "data".getBytes(), acls, CreateMode.PERSISTENT);
}
byte[] data = zooKeeper.getData(znodePath, null, null);
System.out.println("Result: " + new String(data, "UTF-8"));
ご覧のとおり、ノードの作成時に ACL を構成できます。これも重要な機能です。ACL は、ZNode でのアクションに適用される権限です。設定項目が多いので詳細は公式ドキュメント「
Zookeeper ACL Permissions」を参照することをお勧めします。
結論
なぜこれを読んだのでしょうか? Zookeeper は他の一般的なテクノロジーでも使用されているためです。たとえば、Apache Kafka には Zookeeper が必要です。これについては、「
Kafka クイック スタート ガイド」を参照してください。これは NOSQL データベース HBase でも使用されており、詳細については「
HBase クイックスタート ガイド」を参照してください。実際、他の多くのプロジェクトでも Zookeeper が使用されています。それらの一部は「
現実世界での Zookeeper の使用」にリストされています。「なぜ」という質問に答えられたと思います。今最も重要な質問は、「次は何ですか?」です。まず、Apache Zookeeper に関する次の書籍を読むことができます。
次に、Zookeeper に関する優れたビデオ レポートがあります。推奨される視聴:
第三に、世界の全体像を補足する役立つ記事がいくつかあります。
非常に短いレビューですが、入門編として参考になれば幸いです。#ヴィアチェスラフ
GO TO FULL VERSION