第2章 zookeeper安装和配置
2.1.1 zookeeper安装
下载zookeeper安装包,解压到相应目录即可。
2.1.2 zookeeper配置
zookeeper配置有三种模式:单机模式、伪集群模式,集群模式。
2.1.2.1 单机模式
进入zookeeper目录下的conf子目录, 创建zoo.cfg
配置如下: tickTime=2000
dataDir=/Users/zookeeper/data dataLogDir=/Users/zookeeper/logs clientPort=4180 参数说明:
tickTime: zookeeper中使用的基本时间单位, 毫秒值 dataDir: 数据目录. 可以是任意目录
dataLogDir: log目录, 同样可以是任意目录. 如果没有设置该参数, 将使用和dataDir相同的设置 clientPort: 监听client连接的端口号
zookeeper的单机模式已经配置完成. 启动server只需运行脚本。 Server启动之后, 就可以启动client连接server了。
2.1.2.2 伪集群模式
所谓伪集群, 是指在单台机器中启动多个zookeeper进程, 并组成一个集群. 以启动3个zookeeper进程为例.
将zookeeper的目录拷贝2份:
|--zookeeper0 |--zookeeper1 |--zookeeper2
3
配置如下
tickTime=2000 initLimit=5 syncLimit=2
dataDir=/Users//zookeeper0/data dataLogDir=/Users/zookeeper0/logs clientPort=4180
server.0=127.0.0.1:8880:7770 server.1=127.0.0.1:8881:7771 server.2=127.0.0.1:8882:7772 新增了几个参数, 其含义如下:
initLimit: zookeeper集群中的包含多台server, 其中一台为leader, 集群中其余的server为follower. initLimit参数配置初始化连接时, follower和leader之间的最长心跳时间. 此时该参数设置为5, 说明时间限制为5倍tickTime, 即5*2000=10000ms=10s。
syncLimit: 该参数配置leader和follower之间发送消息, 请求和应答的最大时间长度. 此时该参数设置为2, 说明时间限制为2倍tickTime, 即4000ms.
server.X=A:B:C 其中X是一个数字, 表示这是第几号server. A是该server所在的IP地址. B配置该server和集群中的leader交换消息所使用的端口. C配置选举leader时所使用的端口. 由于配置的是伪集群模式, 所以各个server的B, C参数必须不同。
参照zookeeper0/conf/zoo.cfg, 配置zookeeper1/conf/zoo.cfg, 和zookeeper2/conf/zoo.cfg文件. 只需更改dataDir, dataLogDir, clientPort参数即可.
在之前设置的dataDir中新建myid文件, 写入一个数字, 该数字表示这是第几号server. 该数字必须和zoo.cfg文件中的server.X中的X一一对应.
/Users/apple/zookeeper0/data/myid文件中写入0, /Users/apple/zookeeper1/data/myid文件中写入1, /Users/apple/zookeeper2/data/myid文件中写入2.
分别进入/Users/apple/zookeeper0/bin, /Users/apple/zookeeper1/bin, /Users/apple/zookeeper2/bin三个目录, 启动server. 任意选择一个server目录, 启动客户端:
2.1.2.3 集群模式
集群模式的配置和伪集群基本一致,由于集群模式下, 各server部署在不同的机器上,,因此各server的conf/zoo.cfg文件可以完全一样。
4
下面是一个示例:
tickTime=2000 initLimit=5 syncLimit=2
dataDir=/home/zookeeper/data dataLogDir=/home/zookeeper/logs clientPort=4180
server.43=10.1.39.43:2888:3888 server.47=10.1.39.47:2888:3888 server.48=10.1.39.48:2888:3888
示例中部署了3台zookeeper server,分别部署在10.1.39.43, 10.1.39.47, 10.1.39.48上。 需要注意的是,,各server的dataDir目录下的myid文件中的数字必须不同。 10.1.39.43 server的myid为43, 10.1.39.47 server的myid为47, 10.1.39.48 server的myid为48。
5
第3章 Zookeeper C API简介
Zookeeper C API 的声明和描述在 include/zookeeper.h 中可以找到,另外大部分的 Zookeeper C API 常量、结构体声明也在 zookeeper.h 中,如果如果你在使用 C API 是遇到不明白的地方,最好看看 zookeeper.h,或者自己使用 doxygen 生成 Zookeeper C API 的帮助文档。
3.1 Watches
Zookeeper 中最有特色且最不容易理解的是监视(Watches)。Zookeeper 所有的读操作getData(), getChildren(), 和 exists() 都 可以设置监视(watch),监视事件可以理解为一次性的触发器, 官方定义如下: a watch event is one-time trigger, sent to the client that set the watch, which occurs when the data for which the watch was set changes。对此需要作出如下理解:
? (一次性触发)One-time trigger
当设置监视的数据发生改变时,该监视事件会被发送到客户端,例如,如果客户端调用了 getData(\并且稍后 /znode1 节点上的数据发生了改变或者被删除了,客户端将会获取到 /znode1 发生变化的监视事件,而如果 /znode1 再一次发生了变化,除非客户端再次对 /znode1 设置监视,否则客户端不会收到事件通知。
? (发送至客户端)Sent to the client
Zookeeper 客户端和服务端是通过 socket 进行通信的,由于网络存在故障,所以监视事件很有可能不会成功地到达客户端,监视事件是异步发送至监视者的,Zookeeper 本身提供了保序性(ordering guarantee):即客户端只有首先看到了监视事件后,才会感知到它所设置监视的 znode 发生了变化(a client will never see a change for which it has set a watch until it first sees the watch event). 网络延迟或者其他因素可能导致不同的客户端在不同的时刻感知某一监视事件,但是不同的客户端所看到的一切具有一致的顺序。
? (被设置 watch 的数据)The data for which the watch was set
这意味着 znode 节点本身具有不同的改变方式。你也可以想象 Zookeeper 维护了两条监视链表:数据监视和子节点监视(data watches and child watches) getData() and exists() 设置数据监视,getChildren() 设置子节点监视。 或者,你也可以想象 Zookeeper 设置的不同监视返回不同的数据,getData() 和 exists() 返回 znode 节点的相关信息,而 getChildren() 返回子节点列表。因此, setData() 会触发设置在某一节点上所设置的数据监视(假定数据设置成功),而一次成功的 create() 操作则会出发当前节点上所设置的数据监视以及父节点的子节点监视。一次成功的 delete() 操作将会触发当前节点的数据监视和子节点监视事件,同时也会触发该节点父节点的child watch。
6
Zookeeper 中的监视是轻量级的,因此容易设置、维护和分发。当客户端与 Zookeeper 服务器端失去联系时,客户端并不会收到监视事件的通知,只有当客户端重新连接后,若在必要的情况下,以前注册的监视会重新被注册并触发,对于开发人员来说 这通常是透明的。只有一种情况会导致监视事件的丢失,即:通过 exists() 设置了某个 znode 节点的监视,但是如果某个客户端在此 znode 节点被创建和删除的时间间隔内与 zookeeper 服务器失去了联系,该客户端即使稍后重新连接 zookeeper服务器后也得不到事件通知。
3.1.1 监视函数原型
typedef void (*watcher_fn)(zhandle_t *zh, int type, int state, const char *path,void *watcherCtx); 监视函数原型的各个参数解释如下: zh type state path zookeeper 句柄(handle) 事件类型(event type). *_EVENT 常量之一. 连接状态(connection state). 状态值为 *_STATE 常量之一. 触发监视事件的 znode 节点的路径,若为 NULL,则事件类型为 ZOO_SESSION_EVENT watcherCtx 监视器上下文(watcher context).
3.2 常用API
3.2.1.1 zookeeper_init
ZOOAPI 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.
7