前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【zookeeper】 同步API示例入门

【zookeeper】 同步API示例入门

作者头像
王亚昌
发布2018-08-03 15:45:29
1.3K0
发布2018-08-03 15:45:29
举报
文章被收录于专栏:王亚昌的专栏

zookeeper提供了很方便的管理工具,同步API也很方便使用,本文主要介绍以下几个API的用法。

1. zookeeper初始化

zhandle_t *zookeeper_init(const char *host, watcher_fn fn, int recv_timeout, const clientid_t *clientid, void *context, int flags);

功能:

创建一个句柄(handle)和一个响应(response)这个句柄的会话(session)。

参数:

host:zookeeper主机列表,用逗号间隔。

fn:用于监视的回调函数。

clientid:之前建立过连接,现在要重新连的客户端(client)ID。如果之前没有,则为0.

context:暂时用不到,忽略。(TODO)

flags:设置为0,zookeeper开发团队保留以后使用。

2. 监视节点是否存在

int zoo_exists(zhandle_t *zh, const char *path, int watch,  struct Stat *stat);  

功能:

同步监视一个zookeeper节点(node)是否存在。

参数:

zh:zookeeper的句柄,由zookeeper_init得到。

path:节点名称,就是一个类似于文件系统写法的路径。

watch:设置为0,则无作用。设置为非0时,暂时用不到,忽略。(TODO)

stat:(TODO)

返回值:ZOK,ZNONODE,ZNOAUTH,ZBADARGUMENTS,ZINVALIDSTATE,ZMARSHALLINGERROR。ZOK表示操作成功,ZNONODE表示该节点不存在,ZNOAUTH表示客户端(client)无权限,ZINVALIDSTATE表示存在非法的参数,后两者暂略(TODO)。

3. 新建zookeeper节点

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);  

功能:

创建一个同步的zookeeper节点。

参数:

zh:zookeeper的句柄,由zookeeper_init得到。

path:节点名称,就是一个类似于文件系统写法的路径。

value:欲存储到该节点的数据。如果不存储数据,则设置为NULL。

valuelen:欲存储的数据的长度。如果不存储数据,则设置为-1.

acl:初始的ACL节点,ACL不能为空。比如设置为&ZOO_OPEN_ACL_UNSAFE。(TODO)

flags:一般设置为0.(TODO)

path_buffer:将由新节点填充的路径值。可设置为NULL。(TODO)

path_buffer_len:path_buffer的长度。

返回值:ZOK,ZNONODE,ZNODEEXISTS,ZNOAUTH,ZNOCHILDRENFOREPHEMERALS,ZBADARGUMENTS,ZINVALIDSTATE,ZMARSHALLINGERROR。ZOK表示操作成功,ZNONODE表示该节点不存在,ZNODEEXISTS表示节点已经存在,ZNOAUTH表示客户端(client)无权限,ZNOCHILDRENFOREPHEMERALS表示不能够创建临时(ephemeral)节点的子节点(children),ZINVALIDSTATE表示存在非法的参数,后两者暂略(TODO)。

4. 设置zookeeper节点

int zoo_set(zhandle_t *zh, const char *path, const char *buffer, int buflen, int version);  

功能:

向zookeeper节点写数据。

参数:

zh:zookeeper的句柄,由zookeeper_init得到。

path:节点名称,就是一个类似于文件系统写法的路径。

buffer:欲写的数据。

buflen:欲写的数据的长度。

version:检查这个节点的版本是否为version。当设置为-1时,不会进行版本检查。(TODO)

5. 获取某节点的子节点

int zoo_wget_children(zhandle_t *zh, const char *path, watcher_fn watcher, void* watcherCtx, struct String_vector *strings);  

功能:

同步列出一个节点的所有子节点。

参数:

zh:zookeeper的句柄,由zookeeper_init得到。

path:节点名称,就是一个类似于文件系统写法的路径。

watcher:若设置为非0,则zookeeper服务器(server)会设置一个监视器,用来在节点发生改变时通知客户端(client)。

watcherCtx:传送给watcher作为回调的具体用户数据(user specific data)。

strings:用来保存得到的子节点路径。

返回值:ZOK,ZNONODE,ZNOAUTH,ZBADARGUMENTS,ZINVALIDSTATE,ZMARSHALLINGERROR。

在链接的时候需要注意下,官方一共提供了两组库,xxx_st.a和xxx_mt.a,其中xxx_mt.a 支持同步api,链接的时间一定要注意,demo代码如下:

代码语言:javascript
复制
#include <zookeeper.h>
#include <zookeeper_log.h>
#include <iostream>
#include <string.h>

using namespace std;

const char* host = "127.0.0.1:2181";
const int timeout = 2000;
zhandle_t* zkhandle = NULL;
bool is_connect = false;

void clients_watcher_g(zhandle_t * zh, int type, int state, const char* path, void* watcherCtx) {
    printf("global watcher - type:%d,state:%d\n", type, state);
    if ( type==ZOO_SESSION_EVENT ) {
        if ( state==ZOO_CONNECTED_STATE ) {
            printf("connected to zookeeper service successfully!\n");
            printf("timeout:%d\n", zoo_recv_timeout(zh));
            is_connect = true;
        }
        else if ( state==ZOO_EXPIRED_SESSION_STATE ) {
            printf("zookeeper session expired!\n");
        }
    }
    else {
        printf("other type:%d\n", type);
    }
}

int main(int argc, char* argv[]) 
{
    //Init and connect
    zoo_set_debug_level(ZOO_LOG_LEVEL_WARN);
    if (zkhandle) 
        zookeeper_close(zkhandle);

    zkhandle = zookeeper_init(host, clients_watcher_g, timeout, 0, NULL, 0);
    if (NULL == zkhandle) {
        printf("zookeeper init error\n");
        return 0;
    }

    Stat stat;
    int ret = 0;
       char path[] = "/app_watch";
    //check exist
       ret = zoo_exists(zkhandle, path, 0, &stat);
    printf("[%s] ret=%d msg=%s\n", path, ret, ret==0? "succ" : "error");
       if (ZNONODE == ret) {
        // create
        int ret = zoo_create(zkhandle, path, NULL, -1, &ZOO_OPEN_ACL_UNSAFE, 0, NULL, 0); 
        printf("create [%s] ret=%d\n", path, ret);
    }

    //check exist
    ret = zoo_exists(zkhandle, "/app_invalid", 0, &stat);
    printf("ret=%d msg=%s\n", ret, ret==0? "succ" : "error");
    char buffer[1024];
    int buff_len;

    //get data
    buff_len = sizeof(buffer);
    bzero(buffer, buff_len);
    ret = zoo_get(zkhandle, "/app1/p_1", 0, buffer, &buff_len, &stat);
    printf("ret=%d stat=%d len=%d buffer=%s\n", ret, stat.ctime, buff_len, buffer);

        //set data
    buff_len = sizeof(buffer);
        snprintf(buffer, buff_len, "\"rank\":\"10.101.1.101\"");
    ret = zoo_set(zkhandle, "/app1/p_1", (const char *)buffer, strlen(buffer), stat.version);
    printf("ret=%d\n", ret);

    zookeeper_close(zkhandle);
}

执行后输出如下:

[/app_watch] ret=0 msg=succ global watcher - type:-1,state:3 ret=-101 msg=error connected to zookeeper service successfully! timeout:4000 ret=0 stat=1591592808 len=21 buffer="rank":"10.101.1.101" ret=0

附上makefile,方便大家检查链接问题:

代码语言:javascript
复制
BIN = $(patsubst %.cc,%,$(wildcard *.cc))

PATH_ZK = ../zookeeper-3.4.6/src/c/
INC = -I $(PATH_ZK)/include/ -I $(PATH_ZK)/generated
LIB = $(PATH_ZK)/.libs/libzkmt.a $(PATH_ZK)/.libs/libzookeeper_mt.a $(PATH_ZK)/.libs/libhashtable.a
#LIB = $(PATH_ZK)/.libs/libzkst.a $(PATH_ZK)/.libs/libzookeeper_mt.a $(PATH_ZK)/.libs/libhashtable.a

RED = \\e[1m\\e[31m
RESET = \\e[m
GREEN = \\e[1m\\e[32m

all:$(BIN)

%:%.cc
	@echo -e "Make $(GREEN)$@$(RESET) begin......\c"
	g++ -g -pthread -o $@ $< $(INC) $(LIB)
	@echo -e $(RED)"ok."$(RESET)

clean:
	rm $(BIN) 
	@echo "make clean done."

最后附上错误码表和枚举定义,方便自己和大家查阅:

以下定义在zookeeper.h中

代码语言:javascript
复制
enum ZOO_ERRORS {
  ZOK = 0, /*!< Everything is OK */

  /** System and server-side errors.
   * This is never thrown by the server, it shouldn't be used other than
   * to indicate a range. Specifically error codes greater than this
   * value, but lesser than {@link #ZAPIERROR}, are system errors. */
  ZSYSTEMERROR = -1,
  ZRUNTIMEINCONSISTENCY = -2, /*!< A runtime inconsistency was found */
  ZDATAINCONSISTENCY = -3, /*!< A data inconsistency was found */
  ZCONNECTIONLOSS = -4, /*!< Connection to the server has been lost */
  ZMARSHALLINGERROR = -5, /*!< Error while marshalling or unmarshalling data */
  ZUNIMPLEMENTED = -6, /*!< Operation is unimplemented */
  ZOPERATIONTIMEOUT = -7, /*!< Operation timeout */
  ZBADARGUMENTS = -8, /*!< Invalid arguments */
  ZINVALIDSTATE = -9, /*!< Invliad zhandle state */

  /** API errors.
   * This is never thrown by the server, it shouldn't be used other than
   * to indicate a range. Specifically error codes greater than this
   * value are API errors (while values less than this indicate a 
   * {@link #ZSYSTEMERROR}).
   */
  ZAPIERROR = -100,
  ZNONODE = -101, /*!< Node does not exist */
  ZNOAUTH = -102, /*!< Not authenticated */
  ZBADVERSION = -103, /*!< Version conflict */
  ZNOCHILDRENFOREPHEMERALS = -108, /*!< Ephemeral nodes may not have children */
  ZNODEEXISTS = -110, /*!< The node already exists */
  ZNOTEMPTY = -111, /*!< The node has children */
  ZSESSIONEXPIRED = -112, /*!< The session has been expired by the server */
  ZINVALIDCALLBACK = -113, /*!< Invalid callback specified */
  ZINVALIDACL = -114, /*!< Invalid ACL specified */
  ZAUTHFAILED = -115, /*!< Client authentication failed */
  ZCLOSING = -116, /*!< ZooKeeper is closing */
  ZNOTHING = -117, /*!< (not error) no server responses to process */
  ZSESSIONMOVED = -118 /*!<session moved to another server, so operation is ignored */ 
};

以下定义在zookeeper.c中

代码语言:javascript
复制
const int ZOOKEEPER_WRITE = 1 << 0;
const int ZOOKEEPER_READ = 1 << 1;

const int ZOO_EPHEMERAL = 1 << 0;
const int ZOO_SEQUENCE = 1 << 1;

const int ZOO_EXPIRED_SESSION_STATE = EXPIRED_SESSION_STATE_DEF;
const int ZOO_AUTH_FAILED_STATE = AUTH_FAILED_STATE_DEF;
const int ZOO_CONNECTING_STATE = CONNECTING_STATE_DEF;
const int ZOO_ASSOCIATING_STATE = ASSOCIATING_STATE_DEF;
const int ZOO_CONNECTED_STATE = CONNECTED_STATE_DEF;
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016年02月01日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档