zookeeper 的介绍以及c api的使用

一、zookeeper 的安装与配置:

1.zookeeper安装

下载:https://zookeeper.apache.org/  建议下载zookeeper 3.4.6稳定版的, 3.5版本的在搭建集群时,会出现服务启动失败的错误。

安装: 解压 即可

安装C 语言 api:

进入./zookeeper/src/c目录

./configure

make

make install

 

2.集群配置

Zookeeper 的配置文件在 conf 目录下,这个目录下有 zoo_sample.cfg 和 log4j.properties,需要将 zoo_sample.cfg 改名为 zoo.cfg,因为 Zookeeper 在启动时会找这个文件作为默认配置文件。下面详细介绍一下,这个配置文件中各个配置项的意义。

 tickTime=2000

 dataDir= /home/zoo/data

 clientPort=2181

  • tickTime:这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
  • dataDir:顾名思义就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。
  • clientPort:这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。

当这些配置项配置好后,你现在就可以启动 Zookeeper 了,启动后要检查 Zookeeper 是否已经在服务,可以通过 netstat – ano 命令查看是否有你配置的 clientPort 端口号在监听服务。

集群模式

Zookeeper 不仅可以单机提供服务,同时也支持多机组成集群来提供服务。实际上 Zookeeper 还支持另外一种伪集群的方式,也就是可以在一台物理机上运行多个 Zookeeper 实例,下面将介绍集群模式的安装和配置。

Zookeeper 的集群模式的安装和配置也不是很复杂,所要做的就是增加几个配置项。集群模式除了上面的三个配置项还要增加下面几个配置项:

 initLimit=5

 syncLimit=2

 server.1=192.168.211.1:2888:3888

 server.2=192.168.211.2:2888:3888

  • initLimit:这个配置项是用来配置 Zookeeper 接受客户端(这里所说的客户端不是用户连接 Zookeeper 服务器的客户端,而是 Zookeeper 服务器集群中连接到 Leader 的 Follower 服务器)初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过 10 个心跳的时间(也就是 tickTime)长度后 Zookeeper 服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是 5*2000=10 秒
  • syncLimit:这个配置项标识 Leader 与 Follower 之间发送消息,请求和应答时间长度,最长不能超过多少个 tickTime 的时间长度,总的时间长度就是 2*2000=4 秒
  • server.myid=ip:port1:port2:其中 myid 是一个数字,表示这个是第几号服务器;ip是这个服务器的 ip 地址;port1表示的是这个服务器与集群中的 Leader 服务器交换信息的端口;port2表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。如果是伪集群的配置方式,由于 ip 都是一样,所以不同的 Zookeeper 实例通信端口号不能一样,所以要给它们分配不同的端口号。

除了修改 zoo.cfg 配置文件,集群模式下还要配置一个文件 myid,这个文件在 dataDir 目录下,这个文件里面就有一个数据就是 A 的值,Zookeeper 启动时会读取这个文件,拿到里面的数据与 zoo.cfg 里面的配置信息比较从而判断到底是那个 server。

二、Zookeeper的使用:

1.服务端的启动:

进入/bin目录,使用./zkServer.sh start 启动zookeeper服务。 使用./zkServer.sh stop 停止服务。./zkServer.sh status 查看服务状态 (leader or follower).

2.客户端命令的使用:

进入/bin目录下,使用 ./zkCli.sh –server host:port 登陆服务,例如

./zkCli.sh  -server 192.168.1.91:2181,键入任意字符出现以下help命令。

[zk: localhost:2181(CONNECTED) 1] help
ZooKeeper -server host:port cmd args
        connect host:port
        get path [watch]
        ls path [watch]
        set path data [version]
        delquota [-n|-b] path
        quit 
        printwatches on|off
        create [-s] [-e] path data acl
        stat path [watch]
        close 
        ls2 path [watch]
        history 
        listquota path
        setAcl path acl
        getAcl path
        sync path
        redo cmdno
        addauth scheme auth
        delete path [version]
        setquota -n|-b val path

 

  1. create [-s] [-e] path data acl
    其中”-s”表示创建一个顺序自动编号的节点,”-e”表示创建一个临时节点.默认为持久性节点

例如:创建一个持久性节点和临时节点

[zk: localhost:2181(CONNECTED) 7] create /test null

Created /test

[zk: localhost:2181(CONNECTED) 8] create -e /test0 null

Created /test0

当会话退出,临时节点将会自动删除,并且临时节点无子节点。

关于ACL的设置和使用在下一节单独介绍。

2.get path [watch]和set path data [version]

get是获取Znode的数据及相关属性,而set是修改此Znode的数据.

 

3.ls path [watch]

查看Znode的子节点

 

4.stat path [watch]

查看Znode的属性

 

5.delete path [version]

删除Znode,前提若有子节点,先删除其子节点

 

6.addauth scheme auth

认证授权,若某个节点需要认证后才能查看,就需要此命令,具体见下节。

 

3.ACL 的使用

 传统的文件系统中,ACL分为两个维度,一个是属组,一个是权限,子目录/文件默认继承父目录的ACL。而在Zookeeper中,node的ACL是没有继承关系的,是独立控制的.

多集群共用zookeeper又涉及一个权限隔离的问题。zookeeper本身提供了ACL机制,表示为scheme:id:permissions,第一个字段表示采用哪一种机制,第二个id表示用户,permissions表示相关权限,如只读,读写,管理等。

scheme: scheme对应于采用哪种方案来进行权限管理,zookeeper实现了一个pluggable的ACL方案,可以通过扩展scheme,来扩展ACL的机制。zookeeper-3.4.4缺省支持下面几种scheme:

ž   world: 它下面只有一个id, 叫anyone, world:anyone代表任何人,zookeeper中对所有人有权限的结点就是属于world:anyone的

ž   auth: 它不需要id, 只要是通过authentication的user都有权限(zookeeper支持通过kerberos (http://www.cnblogs.com/jankie/archive/2011/08/22/2149285.html)来进行authencation, 也支持username/password形式的authentication)

ž   digest: 它对应的id为username:BASE64(SHA1(password)),它需要先通过username:password形式的authentication

ž   ip: 它对应的id为客户机的IP地址,设置的时候可以设置一个ip段,比如ip:192.168.1.0/16, 表示匹配前16个bit的IP段

ž   super: 在这种scheme情况下,对应的id拥有超级权限,可以做任何事情(cdrwa)

  另外,zookeeper-3.4.4的代码中还提供了对sasl的支持,不过缺省是没有开启的,需要配置才能启用,具体怎么配置在下文中介绍。
       * sasl: sasl的对应的id,是一个通过sasl authentication用户的id,zookeeper-3.4.4中的sasl authentication是通过kerberos来实现的,也就是说用户只有通过了kerberos认证,才能访问它有权限的node.(关于sasl 参考:http://www.wxdl.cn/cloud/zookeeper-sasl.html)

 

id: id与scheme是紧密相关的,具体的情况在上面介绍scheme的过程都已介绍.

 

permission: zookeeper目前支持下面一些权限:

 

权限

描述

备注

CREATE

有创建子节点的权限

 

READ

有读取节点数据和子节点列表的权限

 

WRITE

有修改节点数据的权限

无创建和删除子节点的权限

DELETE

有删除子节点的权限

 

ADMIN

有设置节点权限的权限

 

 

客户端示例:

  1. create [-s] [-e] path data acl
    create /acl  test world:anyone:rwd

Created  /test

  1. create -s /test/test null digest:test:V28q/NynI4JI3Rk54h0r8O5kMug=:rwcda

Created /test/test0000000000

  1. getAcl  /acl  查看路径的acl信息
  2. setAcl /test digest:test:V28q/NynI4JI3Rk54h0r8O5kMug=:r
  3. setAcl /test auth:username:password:crdwa
  4. addauth /<node-name> digest <username>:<password>

 

ACL的原理:

ZooKeeper 的权限管理通过Server、Client 两端协调完成:

(1) Server

一个ZooKeeper 的节点存储两部分内容:数据状态,状态中包含ACL 信息。创建一个znode 会产生一个ACL 列表,列表中每个ACL 包括:

 权限perms

 验证模式scheme

 具体内容expression:Ids

例如,当scheme="digest" 时, Ids 为用户名密码, 即"root :J0sTy9BCUKubtK1y8pkbL7qoxSw"。ZooKeeper 提供了如下几种验证模式:

Digest: Client 端由用户名和密码验证,譬如user:pwd

Host: Client 端由主机名验证,譬如localhost

Ip:Client 端由IP 地址验证,譬如172.2.0.0/24

World :固定用户为anyone,为所有Client 端开放权限

 

(2) 客户端

Client 通过调用addAuthInfo()(java, c为zoo_add_auth)函数设置当前会话的Author信息。Server 收到Client 发送的操作请求除exists、getAcl 之外,需要进行ACL 验证:对该请求携带的Author 明文信息加密,并与目标节点的ACL 信息进行比较,如果匹配则具有相应的权限,否则请求被Server 拒绝。

 

三、zookeeper原理机制

1.文件系统

Zookeeper维护一个类似文件系统的数据结构:

 

 

每个子目录项如 NameService 都被称作为 znode,和文件系统一样,我们能够自由的增加、删除znode,在一个znode下增加、删除子znode,唯一的不同在于znode是可以存储数据的。

有四种类型的znode:

1、PERSISTENT-持久化目录节点

客户端与zookeeper断开连接后,该节点依旧存在

2、 PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点

客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号

3、EPHEMERAL-临时目录节点

客户端与zookeeper断开连接后,该节点被删除

4、EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点

客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号

2.通知机制

客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、被删除、子目录节点增加删除)时,zookeeper会通知客户端。

Zookeeper 的watch函数时一次性触发的,即一 个watch事件将会在数据发生变更时发送给客户端。例如,如果客户端执行操作getData(“/znode1″, true),而后 /znode1 发生变更或是删除了,客户端都会得到一个  /znode1 的watch事件。如果  /znode1 再次发生变更,则在客户端没有设置新的watch的情况下,是不会再给这个客户端发送watch事件的。

这就是说,一个事件会发送向客户端,但可能在在操作成功的返回值到达发起变动的客户端之前,这个事件还没有送达watch的客户端。Watch是异步发送 的。但ZooKeeper保证了一个顺序:一个客户端在收到watch事件之前,一定不会看到它设置过watch的值的变动。网络时延和其他因素可能会导 致不同的客户端看到watch和更新返回值的时间不同。但关键点是,每个客户端所看到的每件事都是有顺序的。

四、使用场景

1.配置同步:

  1. 搭建zookeeper集群,在集群服务器上创建永久节点如:Authorization
  2. 需要更新缓存的客户机器,连接至集群,并通过zookeeper watch机制对Authorization节点设置watch。
  3. 当数据库认证信息发生变化时,对 Authorization 节点数据进行更新,从而触发客户机的watch 函数,在watch函数中进行更新缓存的操作。

注意事项:

  1. watch 时一次性触发的,因此在watch函数触发后,需要重新注册,从而实现永久监听。
  2. 由于网络原因,或者更新操作过于频繁时,在客户机处理更新操作,没有注册新的watch间隙,数据库的认证信息发生变化时,这时会出现客户端缓存和数据库数据不一致的错误,因此,在watch函数结束后,通过再次获取Authorization的相关信息(程序中使用的是mzxid)与之前的进行比较,若不一致,需要再次进行更新缓存操作。
  3. zookeeper session 失效问题 http://blog.csdn.net/kobejayandy/article/details/26289273当客户端收到SESSIONEXPIRED状态信息后,由于之前设置的watch将失效,因此,进行了关闭之前的连接,重新开始连接,并设置watch函数的操作。

2.集群管理

使用zookeeper可以进行集群管理,主要针对两点

  1. 是否有机器的加入或退出

解决这个问题,可以在约定一个父目录,gropmember,然后再父目录下面,每个机器创建临时节点,并且监听父目录的子节点变化消息,一旦有机器退出集群,对应的子节点也将被删除,其它机器将受到通知。同样,当加入新的机器时,其它机器也将受到通知。

  1. Master的选举

Master的选举与上面的原理大致一致,所有机器创建临时子节点并按顺序编号,每次选择编号最小的子节点对应的机器作为master即可。

 

另外:

zookeeper 

zoo_get(zhandle_t *zh, const char *path, int watch, char *buffer,
int* buffer_len, struct Stat *stat);

1.在传递参数时,buffer_len 的值是buffer缓冲的大小,当zoo_get成功返回后,buffer_len将被至为对应node节点数据的长度

2.如何确定buffer的大小? 可以设置一个大约值,然后当zoo_get 返回后,从stat结构体中获取node数据长度,与返回的buffer_len 进行比较,若是不相符,说明缓冲区小了,这时可以拿到正确的长度,再次get即可。

stat结构体:

struct Stat {
    int64_t czxid;
    int64_t mzxid;
    int64_t ctime;
    int64_t mtime;
    int32_t version;
    int32_t cversion;
    int32_t aversion;
    int64_t ephemeralOwner;
    int32_t dataLength;
    int32_t numChildren;
    int64_t pzxid;
};

你可能感兴趣的:(zookeeper 的介绍以及c api的使用)