Zookeeper C API
客户端使用C语言开发,zookeeper提供了两个库,zookeeper_st(单线程库)以及zookeeper_mt(多线程库)。
zookeeper_st提供了异步API和集成在应用程序用来实现事件循环的回调函数,该库是为了支持pthread库不支持或是不稳定的系统而存在。使用过程中需要通过zoo_interest以及zoo_process实现事件处理以及通知机制。
一般情况下使用zookeeper_mt多线程库,多线程库分为三个线程:主线程、io线程以及completion线程。主线程就是调用API的线程,io线程负责网络通信,而对于异步请求以及watcher的响应,io线程会发送给completion线程完成处理。
回调函数
Zookeeper C API中的各种回调函数原型如下:
监视函数(watcher funciton)原型
typedef void (*watcher_fn)(zhandle_t *zh, int type, int state, const char *path,void *watcherCtx);
监视函数参数
- zh:zookeeper句柄
- type:事件类型(event type),*_EVENT常量之一(后面会提到)
- state:连接状态(connection state),*_STATE常量之一(后面会提到)
- path:触发监视事件zonode节点的路径,如果为NULL,则事件类型为ZOO_SESSION_EVENT
- watcherCtx:监视器上下文
其他回调函数原型
Zookeeper 中还有几种在异步 API(一般以 zoo_a*开头的函数) 中使用的回调函数,根据回调函数处理异步函数返回值类型的不同分为以下几类:
- 处理返回 void 类型的回调函数
- 处理返回 Stat 结构的回调函数
- 处理返回字符串的回调函数
- 处理返回数据的回调函数
- 处理返回字符串列表(a list of string)的回调函数
- 同时处理返回字符串列表(a list of string)和 Stat 结构的回调函数
- 处理返回 ACL 信息的回调函数
具体如下所示:
// 处理返回 void 类型的回调函数
typedef void(* void_completion_t)(int rc, const void *data);
其中rc是异步返回的错误码,data是传入回调函数的自定义参数(下同)。
// 处理返回 Stat 结构的回调函数
typedef void(* stat_completion_t)(int rc, const struct Stat *stat, const void *data);
其中stat指向与znode相关的Stat信息(下同)。
// 处理返回字符串的回调函数
typedef void(* string_completion_t)(int rc, const char *value, const void *data);
其中value返回的字符串。
// 处理返回数据的回调函数
typedef void(* data_completion_t)(int rc, const char *value, int value_len, const struct Stat *stat, const void *data);
其中value表示返回的字节数组,value_len是字节长度。
// 处理返回字符串列表(a list of string)的回调函数
typedef void(* strings_completion_t)(int rc, const struct String_vector *strings, const void *data);
其中strings指向了某个znode节点的所有子节点名称列表结构(下同)。
// 同时处理返回字符串列表(a list of string)和 Stat 结构的回调函数
typedef void(* strings_stat_completion_t)(int rc, const struct String_vector *strings, const struct Stat *stat, const void *data);
// 处理以及返回 ACL 信息的回调函数
typedef void(* acl_completion_t)(int rc, struct ACL_vector *acl, struct Stat *stat, const void *data);
其中acl指向包含某个节点ACL信息的指针。
常用API函数
初始化、销毁Zookeeper句柄
ZOOAPI zhandle_t *zookeeper_init(const char *host, watcher_fn fn,
int recv_timeout,
const clientid_t * clientid,
void *context, int flags);
参数:
- host:逗号隔开的 host:port 对, 每个代表一个 zk server, 例如: “127.0.0.1:3000,127.0.0.1:3001”
- fn:全局的监视器回调函数,当发生事件通知时,该函数会被调用
- clientid:客户端尝试重连的先前会话的ID,如果不需要重连先前的会话,则设置为0。客户端可以通过调用 zoo_client_id来访问一个已经连接上的并且有效的会话ID,如果clientid对应的会话超时,或者由于某种原因 clientid变为无效了,那么zookeeper_init将返回一个非法的 zhandle_t,通过 zhandle_t 的状态可以获知 zookeeper_init 调用失败的原因(通常为 ZOO_EXPIRED_SESSION_STATE)
- context:与zhandle_t实例相关联的“上下文对象”(可以通过该参数为 zhandle_t 传入自定义类型的数据),应用程序可以通过 zoo_get_context 访问它(例如在监视器回调函数中),当然 zookeeper 内部没有用到该参数,所以 context 可以设置为 NULL。
flags:一般设置为0
ZOOAPI int zookeeper_close(zhandle_t * zh);
辅助函数
ZOOAPI void zoo_set_debug_level(ZooLogLevel logLevel);
ZOOAPI void zoo_set_log_stream(FILE * logStream);
ZOOAPI struct sockaddr *zookeeper_get_connected_host(zhandle_t * zh, struct sockaddr
*addr,
socklen_t * addr_len);
ZOOAPI int zookeeper_interest(zhandle_t * zh, int *fd, int *interest,
struct timeval *tv);
返回向zookeeper中注册的事件列表
参数:
- fd:文件描述列表
- interest:事件类型,ZOOKEEPER_WRITE、ZOOKEEPER_READ标志
- select或是poll超时时间
ZOOAPI int zookeeper_process(zhandle_t * zh, int events);
通知zookeeper注册的事件已经发生
参数:
- events:ZOOKEEPER_WRITE、ZOOKEEPER_READ标志
ZOOAPI int zoo_state(zhandle_t * zh);
获取zookeeper连接的状态信息
同步接口
创建、删除节点
ZOOAPI int zoo_create(zhandle_t * zh, const char *path,
const char *value, int valuelen,
const struct ACL_vector *acl, int flags,
char *path_buffer, int path_buffer_len);
参数:
- zh:zookeeper_init返回的zookeeper句柄
- path:节点路径
- value:该节点保存的数据
- valuelen:该节点保存数据的大小。如果 value 被设置为 NULL(该 znode 节点不包含数据),则 valuelen 应该设置为 -1
- acl:该节点初始 ACL,ACL 不能为null 或空
- flags:该参数可以设置为 0,或者创建标识符 ZOO_EPHEMERAL, ZOO_SEQUENCE 的组合或(OR)
- path_buffer:用于保存返回节点新路径(因为设置了 ZOO_SEQUENCE 后 zoo_create 所创建的节点名称与参数 path 提供的名称不同,新的节点名称后面填充了序号),path 字符串以 NULL 结束。path_buffer 可以设置为 NULL,此时 path_buffer_len 等于 0
- path_buffer_len