理解Zookeeper(一):Zookeeper概述
什么是Zookeeper
zookeeper是高性能的分布式协作服务和分布式数据一致性解决方案,由雅虎创建,是Goole Chubby的开源实现,所以你就自然明白Zookeeper和Chubby的关系了。Chubby是一个分布式锁服务,GFS和Big Table都是用它来解决分布式协作的一些问题,其底层一致性实现就是以Paxos算法为基础的。
zookeeper可以保证分布式一致性特性,包括顺序一致性、原子性、单一视图(无论客户端连接哪一个ZK服务器看到的都是一样的数据模型)、可靠性、实时性(在一定时间内客户端可以读取到最新数据状态而不是提交后所有服务器马上就全部更新。)
zookeeper的数据模型是一个树形节点,服务启动后,所有数据加载到内存中这样来提高服务器吞吐并减少延迟。 在分布式框架中,分布式应用面临的最大的问题就是数据一致性。那么Zookeeper就是一个比较好的解决方案。在分布式框架中起到协调作用。
Zookeeper的基本概念
集群角色:
-
Leader:ZK集群的核心角色,通过选举产生,为客户端提供读写服务,也就是处理事务请求
-
Follower:集群状态的跟随者,参加选举,没有被选上就是这个角色,提供读取服务,也就是处理非事务请求,对于收到的事务请求会转发给Leader服务器
-
Observer:观察者角色,不参加选举,但是提供数据读取服务,提供读取服务,也就是处理非事务请求,对于收到的事务请求会转发给Leader服务器
会话:
客户端和ZK的连接,客户端与ZK连接一个TCP的长连接来维持会话,通过这个连接可以检测心跳与服务器保存会话,也可以发送请求并接受服务器响应,也可以接受WATCH事件。
节点有两种类型:
-
集群中的一台机器就叫做一个节点
-
还有就是树形数据单元中的Znode也叫一个节点,有持久节点和临时节点
版本:
ZK的版本和我们常规理解的版本不太一样,它是记录节点数据或者节点子节点的类别或者ACL的修改次数。有一个叫做STAT的数据结构这里面就记录了下面的版本信息。
-
version:当前数据节点数据内容的版本号
-
cversion:当前数据节点子节点的版本号
-
aversion:当前数据节点ACL变更版本号
可以利用这个版本实现分布式的锁服务
悲观锁:悲观并发锁,也叫做排他锁,避免不同事务对对同一数据并发更新操作数据不一致
乐观锁:认为不同事务访问相同数据很少出现相互干扰的情况,所以不需要做严格的并发控制,但是它也是锁。比如对每个数据库表增加一个版本号,修改数据之前读取数据自然也会把版本号读取出来,更新的时候就使用这个版本号,如果版本号为1,更新的时候就使用1,如果更新失败则表示其他事物已经对数据做了修改,这时候就需要其他后续处理。
Watcher:
ZK允许用户在节点上注册watcher,当数据发生变化时,ZK会把这个变化通知发送给客户端。
ACL权限控制:
可以对节点设置权限控制
-
CREATE:创建子节点的读权限
-
READ:获取节点数据和子节点列表的权限
-
WRITE:更新节点数据的权限
-
DELET:删除子节点的权限
-
ADMIN:设置节点ACL的权限
ZAB协议
zookeeper是基于PAXOS算法,但是它自己也有一套核心算法就是ZAB,原子消息广播协议。这个协议是为Zookeeper单独设计的,是崩溃可恢复的的原子消息广播算法。
Zookeeper使用一个单一的主进程来接收并处理客户端所有请求,将服务器的状态以事务的形式广播到所有副本进程中。
ZAB协议包括两种基本模式,崩溃恢复和消息广播。
集群启动过程中,Leader断开、崩溃退出或重启等异常情况,ZAB会进入恢复模式并选举新的Leader,当产生了新的Leader后并集群中过半腐恶去完成了与Leader的状态同步(数据同步),那么ZAB协议退出恢复模式,进入消息广播模式。
如果在当前集群中新加入一台服务器,那么这台新服务器会自动进入恢复模式,待完成与集群Leader的同步之后就进入消息广播模式。
Leader服务器收到客户端的事务请求会生成一个事务提案并发起广播;如果非Leader服务器收到客户端请求后它会把请求转发给Leader服务器。
消息广播:
在广播事务之前Leader服务器会先给这个事务分配一个全局单调递增的唯一ID,也就是事务ID(ZXID),每一个事务必须按照ZXID的先后顺序进行处理。而且Leader服务器会为每一个Follower分配一个单独的队列,然后将需要广播的事务放到队列中。每个Follower服务器再接收到这个事务之后,都会将其以事务日志的形式写入到本地磁盘中,成功写入后反馈给Leader一个ACK,当Leader收到半数ACK响应之后,就会广播一个Commit消息给所有Follower,通知它们进行提交,同时Leader也会完成自身的提交。
崩溃恢复:
其目的就是保证尽快选举出一个新的Leader并通知给其他Follower,同时保证整个集群中的数据状态是一致的。
ZAB协议丢弃那些只有在Leader服务器被提出的事务。