1. ZooKeeper C言語APIのビルド手順
ZooKeeper 3.4.14バージョンを前提として、C言語クライアントライブラリをビルドします。
wget "http://mirrors.hust.edu.cn/apache/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gz"
tar -xzf zookeeper-3.4.14.tar.gz
cd zookeeper-3.4.14/zookeeper-client/zookeeper-client-c
./configure
make
sudo make install
インストール完了後、ヘッダーファイルはデフォルトで /usr/local/include/zookeeper に配置されます。任意のパスにコピーすることも可能です。
2. C言語によるZooKeeper接続の実装例
以下のコードは、ZooKeeperサーバー群に接続し、設定されたウォッチャーを実装した上でのルートノード / の存在チェックを行うシンプルなサンプルです。
#include <zookeeper.h>
#include <zookeeper_log.h>
#include <zookeeper.jute.h>
#include <stdio.h>
// 接続対象のZooKeeperサーバー一覧(評価用に固定設定)
static const char *zk_hosts = "127.0.0.1:12181,127.0.0.1:12182,127.0.0.1:12183";
// セッションイベント時のコールバック関数
static void session_watcher(zhandle_t *zh, int type, int state, const char *path, void *ctx)
{
fprintf(stderr, "watcher fired: type=%d, state=%d, path=%s, ctx=%p\n", type, state, path, ctx);
}
// 指定パスのノード情報を取得(zoo_existsラッパー)
static void check_node_exists(zhandle_t *zk, const char *node_path)
{
struct Stat zstat;
fprintf(stderr, "=== checking node: %s ===\n", node_path);
int rc = zoo_exists(zk, node_path, 0, &zstat);
if (rc == ZOK) {
fprintf(stderr, "node found: path=%s, cversion=%d, numChildren=%d, version=%d\n",
node_path, zstat.cversion, zstat.numChildren, zstat.version);
} else {
fprintf(stderr, "exists check failed: rc=%d\n", rc);
}
}
int main(void)
{
zoo_set_debug_level(ZOO_LOG_LEVEL_DEBUG);
// ZooKeeperセッションの初期化
zhandle_t *handle = zookeeper_init(
zk_hosts,
session_watcher,
50000, // session timeout (ms)
0, // client id
NULL, // client context
0 // flags
);
if (!handle) {
fprintf(stderr, "failed to initialize ZooKeeper client\n");
return -1;
}
// ルートノードの存在確認
check_node_exists(handle, "/");
// セッション終了
zookeeper_close(handle);
return 0;
}
3. Makefileによるコンパイル設定
ZK_LIB_DIR := /usr/local
ZK_INC_DIR := $(ZK_LIB_DIR)/include/zookeeper
ZK_SRC_DIR := .
ZK_LIB_NAME := zookeeper_mt
TARGET := zk_client_demo
SRC := $(wildcard $(ZK_SRC_DIR)/*.c)
CC := gcc
CFLAGS := -g -DTHREADED
LDFLAGS := -L$(ZK_LIB_DIR)/lib -l$(ZK_LIB_NAME)
$(TARGET): $(SRC)
$(CC) $(CFLAGS) -I$(ZK_INC_DIR) $^ -o $@ $(LDFLAGS)
clean:
rm -f $(TARGET)
ビルド後、実行すると以下のようなログが出力されます。
...
ZOO_INFO@zookeeper_init: Initiating client connection...
watcher fired: type=-1, state=3, path=(null), ctx=(nil)
=== checking node: / ===
node found: path=/, cversion=8, numChildren=2, version=0
...
4. 結果の照合例
出力された統計情報は、ZooKeeper CLIツールで得られる情報と互換性があります。
[zk: 127.0.0.1:12181(CONNECTED) 0] get /
cZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
cversion = 8
dataVersion = 0
numChildren = 2
...
この結果より、クライアントは正しくセッション確立後、ノードメタ情報を取得できていることが確認できます。