1概要


https://zookeeper.apache.org/


は、分散アプリケーションの開発を容易にする分散調整サービス

です。 Apache Hadoop、HBase、https://cwiki.apache.org/confluence/display/ZOOKEEPER/PoweredByなどのプロジェクトでリーダーの選定、構成管理、ノード調整、サーバーリース管理などのさまざまな用途で使用されます

  • ZooKeeperクラスタ内のノードは、標準のファイルシステムまたはツリーデータ構造に似た共有階層名前空間** にデータを格納します。

この記事では、Apache ZookeeperのJava APIを使用してZooKeeper内に格納されている情報を格納、更新、削除する方法を探ります。

2.

設定

Apache ZooKeeper Javaライブラリの最新版はhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.apache.zookeeper%22%20AND%20a%3A%22zookeeperにあります%22[ここ]:

<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.11</version>
</dependency>


3 ZooKeeperデータモデル – ZNode

ZooKeeperは、ステータス情報、調整情報、位置情報などの調整データを格納する分散ファイルシステムによく似た階層的な名前空間を持ちます。この情報はさまざまなノードに格納されます。

ZooKeeperツリーのすべてのノードはZNodeと呼ばれます。

各ZNodeは、データまたはACLの変更に対するバージョン番号とタイムスタンプを管理します。また、これによりZooKeeperはキャッシュを検証し、更新を調整することができます。


4インストール


4.1. インストール

最新のZooKeeperリリースはhttps://www.apache.org/dyn/closer.cgi/zookeeper/[こちら]からダウンロードできます。その前に、https://zookeeper.apache.org/doc/r3.3.5/zookeeperAdmin.html#sc__systemReq[ここ]に記載されているシステム要件を満たしていることを確認する必要があります。


4.2. スタンドアロンモード

この記事では、最小限の設定でZooKeeperをスタンドアロンモードで実行します。

ここ

に記載されている手順に従ってください。

注:スタンドアローンモードではレプリケーションは行われないため、ZooKeeperプロセスが失敗するとサービスは停止します。


5 ZooKeeper CLIの例

ZooKeeperと対話するために、ZooKeeperのコマンドラインインターフェース(CLI)を使用します。

bin/zkCli.sh -server 127.0.0.1:2181

上記のコマンドは、スタンドアロンインスタンスをローカルで起動します。 ZNodeを作成し、ZooKeeper内に情報を格納する方法を見てみましょう。

----[zk: localhost:2181(CONNECTED) 0]create/MyFirstZNode ZNodeVal
Created/FirstZnode
----

ZooKeeperの階層的な名前空間のルートに “MyFirstZNode”を作成し、それに “ZNodeVal”を記述しました。

フラグを渡していないので、作成されたZNodeは永続的になります。

ZNodeに関連付けられているデータとメタデータを取得するための__getコマンドを発行しましょう。

----[zk: localhost:2181(CONNECTED) 1]get/FirstZnode

“Myfirstzookeeper-app”
cZxid = 0x7f
ctime = Sun Feb 18 16:15:47 IST 2018
mZxid = 0x7f
mtime = Sun Feb 18 16:15:47 IST 2018
pZxid = 0x7f
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 22
numChildren = 0

__set__オペレーションを使用して既存の__ZNode__のデータを更新できます。

例えば:

[source,bash,gutter:,true]

set/MyFirstZNode ZNodeValUpdated

これにより、__MyFirstZNode__のデータが__ZNodeVal__から__ZNodeValUpdatedに更新されます。

===  **  6. **  ZooKeeper Java APIの例

それでは、Zookeeper Java APIを見てノードを作成し、ノードを更新してデータを取得しましょう。

====  **  6.1.  Javaパッケージ**

ZooKeeper Javaバインディングは、主に2つのJavaパッケージで構成されています。

. のメインクラスを定義する____org.apache.zookeeper ____ ** ** :** **

ZooKeeperクライアントライブラリと多くの静的定義
ZooKeeperのイベントタイプと状態
。 __org.apache.zookeeper.data__:特性を定義します

アクセス制御リスト(ACL)、ID、統計などのZノードに関連付けられている

__org.apache.zookeeper.server__、__org.apache.zookeeper.server.quorum__、__org.apache.zookeeper.server.upgrade__など、ZooKeeper Java APIもサーバーの実装に使用されています。

ただし、それらはこの記事の範囲を超えています。

====  **  6.2.  ZooKeeperインスタンスへの接続**

それでは、既に実行中のZooKeeperへの接続と切断に使用する__ZKConnection__クラスを作成しましょう。

[source,java,gutter:,true]

public class ZKConnection {
private ZooKeeper zoo;
CountDownLatch connectionLatch = new CountDownLatch(1);

//...

public ZooKeeper connect(String host)
  throws IOException,
  InterruptedException {
    zoo = new ZooKeeper(host, 2000, new Watcher() {
        public void process(WatchedEvent we) {
            if (we.getState() == KeeperState.SyncConnected) {
                connectionLatch.countDown();
            }
        }
    });

    connectionLatch.await();
    return zoo;
}

    public void close() throws InterruptedException {
        zoo.close();
    }
}

ZooKeeperサービスを使用するには、アプリケーションはまずZooKeeperクライアントライブラリ** のメインクラスである**  __ZooKeeper__ classのオブジェクトをインスタンス化する必要があります。

__connect__メソッドでは、__ZooKeeper__クラスのインスタンスをインスタンス化しています。また、ZooKeeperからの__WatchedEvent__を処理して接続を受け付けるようにするためのコールバックメソッドを登録し、__CountDownLatch__の__countdown__メソッドを使用して__connect__メソッドを終了しました。

サーバーへの接続が確立されると、セッションIDがクライアントに割り当てられます。セッションを有効に保つために、クライアントは定期的にハートビートをサーバーに送信する必要があります。

セッションIDが有効である限り、クライアントアプリケーションはZooKeeper APIを呼び出すことができます。

====  **  6.3. クライアント操作**

ZNodeの作成とデータの保存、ZNodeデータの取得と更新など、さまざまな操作を公開する__ZKManager__インターフェースを作成します。

[source,java,gutter:,true]

public interface ZKManager {
public void create(String path, byte[]data)
throws KeeperException, InterruptedException;
public Object getZNodeData(String path, boolean watchFlag);
public void update(String path, byte[]data)
throws KeeperException, InterruptedException;
}

上記のインターフェースの実装を見てみましょう。

[source,java,gutter:,true]

public class ZKManagerImpl implements ZKManager {
private static ZooKeeper zkeeper;
private static ZKConnection zkConnection;

public ZKManagerImpl() {
    initialize();
}

private void initialize() {
    zkConnection = new ZKConnection();
    zkeeper = zkConnection.connect("localhost");
}

public void closeConnection() {
    zkConnection.close();
}

public void create(String path, byte[]data)
  throws KeeperException,
  InterruptedException {

    zkeeper.create(
      path,
      data,
      ZooDefs.Ids.OPEN__ACL__UNSAFE,
      CreateMode.PERSISTENT);
}

public Object getZNodeData(String path, boolean watchFlag)
  throws KeeperException,
  InterruptedException {

    byte[]b = null;
    b = zkeeper.getData(path, null, null);
    return new String(b, "UTF-8");
}

    public void update(String path, byte[]data) throws KeeperException,
      InterruptedException {
        int version = zkeeper.exists(path, true).getVersion();
        zkeeper.setData(path, data, version);
    }
}

上記のコードでは、__connect__と__disconnect__の呼び出しは、以前に作成された__ZKConnection__クラスに委任されています。私たちの__create__メソッドはバイト配列データから与えられたパスにZNodeを作成するために使われます。デモンストレーションのみを目的として、ACLを完全に公開しました。

一度作成されたZNodeは永続的なものであり、クライアントが切断しても削除されません。

私たちの__getZNodeData__メソッドでZooKeeperからZNodeデータを取得するロジックはとても簡単です。最後に、__update__メソッドを使って、与えられたパス上のZNodeの存在をチェックし、存在すればそれを取得します。

それを超えて、データを更新するために、我々は最初にZNodeの存在をチェックして現在のバージョンを取得します。次に、パラメータとしてZNode、データ、および現在のバージョンのパスを指定して__setData__メソッドを呼び出します。渡されたバージョンが最新バージョンと一致する場合にのみ、ZooKeeperはデータを更新します。

===  **  7. 結論**

分散アプリケーションを開発するとき、Apache ZooKeeperは分散調整サービスとして重要な役割を果たします。特に、共有設定の保存、マスターノードの選択などのユースケース用です。

ZooKeeperは、ZooKeeper ZNodeとシームレスに通信するためにクライアントサイドのアプリケーションコードで使用されるエレガントなJavaベースのAPIも提供します。

そしていつものように、このチュートリアルのためのすべての情報源はhttps://github.com/eugenp/tutorials/tree/master/apache-zookeeper[Github上で動く]にあります。