JavaとZookeeperの使用開始
1. 概要
Apache ZooKeeperis a distributed coordination serviceこれにより、分散アプリケーションの開発が容易になります。 これは、Apache Hadoop、HBase、othersなどのプロジェクトで、リーダーの選出、構成管理、ノード調整、サーバーリース管理などのさまざまなユースケースで使用されます。
Nodes within ZooKeeper cluster store their data in a shared hierarchal namespaceは、標準のファイルシステムまたはツリーデータ構造に似ています。
この記事では、ApacheZookeeperのJavaAPIを使用して、ZooKeeper内に保存されている情報を保存、更新、削除する方法について説明します。
2. Setup
Apache ZooKeeper Javaライブラリの最新バージョンはhereにあります。
org.apache.zookeeper
zookeeper
3.4.11
3. ZooKeeperデータモデル– ZNode
ZooKeeperには階層型のネームスペースがあり、ステータス情報、調整情報、位置情報などの調整データを保存する分散ファイルシステムによく似ています。 この情報は異なるノードに保存されます。
ZooKeeperツリー内のすべてのノードはZNodeと呼ばれます。
各ZNodeは、データまたはACLの変更のバージョン番号とタイムスタンプを維持します。 また、これにより、ZooKeeperはキャッシュを検証し、更新を調整できます。
4. インストール
5. ZooKeeperCLIの例
次に、ZooKeeperコマンドラインインターフェイス(CLI)を使用してZooKeeperと対話します。
bin/zkCli.sh -server 127.0.0.1:2181
上記のコマンドは、スタンドアロンインスタンスをローカルで起動します。 次に、ZNodeを作成し、ZooKeeper内に情報を保存する方法を見てみましょう。
[zk: localhost:2181(CONNECTED) 0] create /MyFirstZNode ZNodeVal
Created /FirstZnode
ZooKeeper階層名前空間のルートにZNode‘MyFirstZNode’を作成し、それに‘ZNodeVal’を書き込みました。
フラグを渡していないため、作成されたZNodeは永続的です。
次に、‘get'コマンドを発行して、ZNodeに関連付けられたデータとメタデータをフェッチします。
[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のデータを更新できます。
例えば:
set /MyFirstZNode ZNodeValUpdated
これにより、MyFirstZNodeのデータがZNodeValからZNodeValUpdated.に更新されます。
6. ZooKeeper JavaAPIの例
次に、Zookeeper Java APIを見て、ノードを作成し、ノードを更新して、いくつかのデータを取得しましょう。
6.1. Javaパッケージ
ZooKeeper Javaバインディングは、主に2つのJavaパッケージで構成されています。
-
org.apache.zookeeper:は、ZooKeeperクライアントライブラリのメインクラスと、ZooKeeperイベントタイプおよび状態の多くの静的定義を定義します。
-
org.apache.zookeeper.data:アクセス制御リスト(ACL)、ID、統計など、ZNodeに関連付けられた特性を定義します
org.apache.zookeeper.server、org.apache.zookeeper.server.quorum、org.apache.zookeeper.server.upgradeなどのZooKeeper JavaAPIもサーバー実装で使用されます。
ただし、これらはこの記事の範囲を超えています。
6.2. ZooKeeperインスタンスへの接続
次に、すでに実行中のZooKeeperへの接続と切断に使用されるZKConnectionクラスを作成しましょう。
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 class, which is the main class of ZooKeeper client libraryのオブジェクトをインスタンス化する必要があります。
connectメソッドでは、ZooKeeperクラスのインスタンスをインスタンス化しています。 また、接続を受け入れるためにZooKeeperからのWatchedEventを処理し、それに応じてCountDownLatchのcountdownメソッドを使用してconnectメソッドを終了するコールバックメソッドを登録しました。
サーバーへの接続が確立されると、セッションIDがクライアントに割り当てられます。 セッションを有効に保つために、クライアントは定期的にサーバーにハートビートを送信する必要があります。
セッションIDが有効である限り、クライアントアプリケーションはZooKeeper APIを呼び出すことができます。
6.3. クライアントオペレーション
次に、ZNodeの作成やデータの保存、ZNodeデータのフェッチと更新など、さまざまな操作を公開するZKManagerインターフェースを作成します。
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;
}
上記のインターフェースの実装を見てみましょう。
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も提供します。
そしていつものように、このチュートリアルのすべてのソースはover on Githubで見つけることができます。