记录下zk的学习。
ZooKeeper是一个开源的分布式协调服务。分布式应用程序可以基于zk实现数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等。
1、zk数据模型
zk服务器在内存中维护着一个共享的树形结构的名字空间,由一系列ZNode的数据结点组成。zk将全量数据存储在内存中,以此来实现提高服务器吞吐和减少延迟。
zk服务器可以有多台服务器构成一个集群,集群中的每台服务器都会在内存中维护当前的服务器状态,并且保持相互通信。客户端和任何一台服务器创建TCP连接,连接断开后会自动连接到集群中的其他机器上。
2、更新请求顺序访问
对于来自客户端的每个更新请求,zk都会分配一个全局唯一的递增编号,用此编号来保证所有事务操作的先后顺序。每个事务请求都需要集群中过半机器投票认可才能被真正应用到zk的内存数据库中去。
3、zk服务器集群由群首、追随者和观察者组成。
群首:为客户端提供读和写服务。对客户端发起的zk更新请求进行排序,包括:create、setData和delete操作。群首将每一个更新请求转换为一个事务,并发送给追随者,确保集群按照群首确定的顺序接受并处理这些事务。
追随者:为客户端提供读服务。接受群首分配的事务请求,并执行,参与群首选举。
观察者:为客户端提供读服务。不参与选举,不参与写操作的‘过半写成功’策略。提高读操作吞吐率。
4、独立模式:只有一台zk服务器
仲裁模式:有一组zk服务器。
会话:指客户端与服务器之间的TCP长连接。
数据节点(ZNode):zk中节点分为两类: 第一类是构成集群中的机器,即机器节点;第二类是指数据模型中的数据单元,即数据节点(ZNode)。ZNode可以分为持久节点和临时节点两类。持久节点是指一旦ZNode被创建了,除非主动进行ZNode的移除,否则这个ZNode将一直保存在zk上。临时节点的生命周期和客户端会话绑定,一旦会话失效,那么客户端创建的所有临时节点都会被移除。
版本:zk上的每个ZNode节点都会存储数据,对应于每个ZNode,zk都会为其维护一个叫做Stat的数据结构,Stat中记录了ZNode的三个数据版本,分别是version(当前ZNode的版本)、cversion(当前节点子节点的版本)和aversion(当前ZNode的ACL版本)
Watcher:事件监视器。zk允许用户在指定节点上注册一些watcher,并且在特定事件触发的时候,zk服务器会将事件通知到感兴趣的客户端上去。
ACL:Access Control Lists策略。zk采用此策略进行权限控制。
5、ZAB协议(ZooKeeper Atomic Broadcast):zk原子消息广播协议
是zk实现数据一致性的核心算法。ZAB原子广播协议将服务器的状态变更请求以事务Proposal的形式广播到所有集群中的跟随者服务器。ZAB协议核心是定义了对于会改变zk服务器数据状态的事务请求的处理方式。具体如下:
“所有事务请求均由一个全局唯一的服务器来协调处理,即群首服务器。群首服务器负责将一个客户端事务请求转换成一个事务Proposal,并将该Proposal分发给集群中所有的跟随者服务器,之后群首服务器需要等待所有追随者服务器的反馈,一旦超过半数的追随者服务器进行了正确的反馈,那么群首就会再次向所有的追随者服务器分发Commit消息,要求追随者将前一个Proposal进行提交。”
当群首服务器向参与者发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者发生了故障,这回导致只有一部分参与者接受到了commit请求。而在这部分参与者接到commit请求之后就会执行commit操作。但是其他部分未接到commit请求的机器则无法执行事务提交。于是整个分布式系统便出现了数据不一致性的现象。
ZAB协议包括两种模式:崩溃恢复和消息广播,上面是消息广播的模式。
如果集群中的其他非群首服务器接收到客户端的事务请求,那么这些服务器首先会将这个事务请求转发给群首服务器。
6、群首选举:当群首服务器挂掉后,ZAB协议进入到崩溃恢复模式,选举一个新的群首服务器,追随者进行选举投票,拥有所有机器最高编号的事务id(zxid)的服务器将赢得选举,也就是处理过最新事务请求的服务器赢得选举。这样可以保证新选举出来的群首服务器一定具有所有已经提交的Proposal(不会丢失更新)。
7、数据同步:在群首选举完成后,正式工作之前,群首服务器会首先确认事务日志中的所有proposal是否都已经被集群中过半的机器提交了,即是否完成数据同步。
群首服务器需要确保所有的追随者 服务器能够接收到每一条事务Proposal,并能够正确地将所有已经提交了的事务Proposal应用到内存数据库中去。群首服务器会为每一个追随者服务器都准备一个队列,并将那些没有被各追随者服务器同步的事务以Proposal消息的形式逐个发送给追随者服务器,并在每个Proposal后紧跟一个Commit消息,表示该事务已经被提交。等追随者服务器将所有尚未同步的事务都会群首那里同步过来并应用到本地数据库之后,群首服务器就会将追随者服务器加入到真正的可用追随者列表中。
8、ZooKeeper的典型应用场景
9、zk在大型分布式系统中的应用
(1)HBase
系统容错:在HBase启动的时候,每个RegionServer服务器都会到zk的/hbase/rs节点下创建一个信息节点,同时HMaster会对这个节点注册监听。当某个RS挂掉的时候,zk会因为无法接收其心跳而删除掉该RS服务器对应的rs状态节点。同时,HMaster则会接收到zk的NodeDelete通知,之后HMaster会将该RS所处理的Region路由到其他节点上,并记录到Meta信息中供客户端查询。
RootRegion管理:对于HBase集群来说,数据存储的位置信息是记录在RootRegion上,每次客户端发起新的请求,需要知道数据的位置,就会查询RootRegion,而RootRegion自身的位置则记录在ZooKeeper上。当RootRegion发生变化,就能够通过zk来感知到。
Region状态管理:Region是HBase中存储数据的物理切片。而Region会经常发生变更,比如Region分列于合并,当Region变化时,就会经理Offlin和重新Online的构成。此状态变化也是由zk来管理,以便让全局知晓。
分布式SplitLog任务管理:当某台RS服务器挂掉的时候,总有一部分新写入数据还没有持久化到HFile中,在迁移该RS时,需要从HLog中恢复这部分还在内存中的数据,其中一步就是SplitLog,即HMaster需要遍历该RS服务器的Hlog,进行数据的恢复。由于日志量庞大,HMaster会在zk上创建一个splitlog的节点,将“哪个RS处理哪个Region”信息以列表的形式存放到该节点上,由RS服务器自己到该节点上领取任务,在任务执行成功和失败时更新节点。
Replication管理:Replication是实现HBase主备同步重要模块。HBase借助zk来完成Replication功能。做法是在zk上记录一个replication节点,然后把不同的RS服务器对应的HLog文件名称记录到对应的节点上,HMaster集群会将新增的数据推送给Slave集群,并同时将推送消息记录到ZK上(断点记录),当服务器挂掉时,HMaster可以根据断点信息来协调推送HLog数据的主节点服务器,实现复制。
关于HBase介绍,参考这里。
参考:
一篇文章看懂ZooKeeper内部原理
倪超 《从Paxos到ZooKeeper 分布式一致性原理与实践》