Zookeeper部署及典型应用

什么是zookeeper?

zookeeper是一个针对大型分布式系统的可靠协调系统;
提供的功能包括:配置维护、名字服务、分布式同步、组服务等;
目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。


Zookeeper 架构

Zookeeper部署及典型应用

每个Server在内存中存储了一份数据;
Zookeeper启动时,将从实例中选举一个leader(Paxos协议);
Leader负责处理数据更新等操作(Zab协议);
一个更新操作成功,当且仅当大多数Server在内存中成功修改数据。

Zookeeper部署及典型应用

注:观察者是3.3版本后新加的。为保证系统的可靠性,一般考虑增加server,但如果所有的server都参与投票(超过半数通过认定通过),投票延时太大,影响系统性能,因此将一部分server设置成观察者(不参与投票),这样就可以在保证可靠的同时避免这样的投票延时。

因为投票决议采用超过半数的方式,如3个或4个server的情况都只允许有一个结点宕机(3个要保证2个写成功,4个时要保证3个写成功),所以zookeeper一般设置奇数个server。


Zookeeper数据模型
zookeeper是层次化的目录结构,命名符合常规文件系统规范;
每个节点在zookeeper中叫做Znode,并且其有一个唯一的路径标识;
节点Znode可以包含数据和子节点(ephemeral类型的节点不能有子节点);
Znode中的数据可以有多个版本,比如某一个路径下存有多个数据版本,那么查询这个路径下的数据需带上版本;
客户端应用可以在节点上设置监视器(Watcher);
节点不支持部分读写,而是一次性完整读写。
Znode有两种类型,短暂的(ephemeral)和持久的(persistent);
Znode的类型在创建时确定并且之后不能再修改;
短暂znode的客户端会话结束时,zookeeper会将该短暂znode删除,短暂znode不可以有子节点;
持久znode不依赖于客户端会话,只有当客户端明确要删除该持久znode时才会被删除;
Znode有四种形式的目录节点,PERSISTENT、PERSISTENT_SEQUENTIAL、EPHEMERAL、EPHEMERAL_SEQUENTIAL

Znode目录结构

Zookeeper部署及典型应用

 


Zookeeper应用场景

1.统一命名服务
分布式环境下,经常需要对应用/服务进行统一命名,便于识别不同服务(类似于域名与ip之间对应关系,域名容易记住;通过名称来获取资源或服务的地址,提供者等信息),利用Zookeeper按照层次结构组织服务/应用名称(可将服务名称以及地址信息写到Zookeeper上,客户端通过Zookeeper获取可用服务列表类)。

2.配置管理:
分布式环境下,配置文件管理和同步是一个常见问题(一个集群中,所有节点的配置信息是一致的,比如Hadoop,对配置文件修改后,希望能够快速同步到各个节点上)配置管理可交由Zookeeper实现(可将配置信息写入Zookeeper的一个znode上,各个节点监听这个znode,一旦znode中的数据被修改,zookeeper将通知各个节点)

3.集群管理:
分布式环境中,实时掌握每个节点的状态是必要的(可根据节点实时状态作出一些调整),可交由Zookeeper实现(可将节点信息写入Zookeeper的一个znode上,监听这个znode可获取它的实时状态变化)。
Example:Hbase中Master状态监控与选举。

4.分布式通知/协调(类似发布/订阅)
分布式环境中,经常存在一个服务需要知道它所管理的子服务的状态,心跳检测机制可通过Zookeeper实现,信息推送可由Zookeeper实现(发布/订阅模式)。

5.分布式锁
分布式环境中,处于一个结点的服务需要顺序的访问每一个资源,保证服务可以正常运行,需要一把分布式锁。Zookeeper是强一致的(多个客户端同时在Zookeeper上创建相同znode,只有一个创建成功),实现锁的独占性(多个客户端同时在Zookeeper上创建相同znode ,创建成功的那个客户端得到锁,其他客户端等待),控制锁的时序(各个客户端在某个znode下创建临时znode(类型为   CreateMode.EPHEMERAL_SEQUENTIAL),这样,该znode可掌握全局访问时序)。

6.分布式队列
(1)同步队列:当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。

案例:一个job由多个task组成,只有所有任务完成后,job才运行完成。可为job创建一个/job目录,然后在该目录下,为每个完成的task创建一个临时znode,一旦临时节点数目达到task总数,则job运行完成。

(2)队列按照 FIFO 方式进行入队和出队操作,例如实现生产者和消费者模型。(可通过分布式锁实现)。


Zookeeper部署

zookeeper下载地址

单机模式:
在conf目录下创建一个配置文件zoo.cfg:
    tickTime=2000 dataDir=/user/local/zookeeper/data
    dataLogDir=/user/local/zookeeper/dataLog
    clientPort=2181
启动/关闭ZooKeeper Server
    启动:bin/zkServer.sh start
    关闭:bin/zkServer.sh stop

伪分布式模式:
1.建了3个文件夹,server1 server2 server3,在每个文件夹中解压zookeeper的下载包
2.创建myid文件:进入data目录,创建名为myid的文件,分别写入一个数字,server1~server3对应的myid文件分别写1~3
3.在conf目录下创建一个配置文件zoo.cfg
tickTime=2000 dataDir=/usr/local/zookeeper/data dataLogDir=/usr/local/zookeeper/server1/
clientPort=2181
initLimit=5
syncLimit=2
server.1=server1:2888:3888
server.2=server2:2889:3889
server.3=server3:2890:3890

分布式模式:
1.创建myid文件
    server1~ server3机器的内容为:1~3
2.在conf目录下创建一个配置文件zoo.cfg:
tickTime=2000
dataDir=/usr/local/zookeeper/data dataLogDir=/usr/local/zookeeper/dataLog
clientPort=2181
initLimit=5
syncLimit=2
server.1=server1:2888:3888
server.2=server2:2888:3888
server.3=server3:2888:3888

注:Observer配置:
修改zoo.cfg中的两个配置:
peerType=observer
server.1:localhost:2181:3181:observer


Zookeeper API

String create (path, data, acl, flags)
void delete (path, expectedVersion)
Stat setData (path, data, expectedVersion)
byte[] getData (path, watch)
Stat exists (path, watch)
String[] getChildren (path, watch)
void sync (path)

更多API详情请参考:https://zookeeper.apache.org/doc/r3.4.6/api/org/apache/zookeeper/ZooKeeper.html

zookeeper案例:https://github.com/sleberknight/zookeeper-samples/tree/master/src/main/java/com/nearinfinity/examples/zookeeper