说说zookeeper【叁】_工作机制和实现原理


上篇文章:说说zookeeper【贰】_ZAB协议


本文简单说说zookeeper的工作机制。


总体来说,客户端先和zookeeper服务器建立起一个TCP长连接(session),之后根据ACL权限的设置,可在zookeeper服务器上对目录和节点(zode)进行操作,同时还可以在节点上注册watcher事件。下面依次展开说明。


session


客户端和服务器之间建立TCP长连接,通过心跳检测和服务器保持有效的会话,也能向zookeeper服务器发送请求和接收响应,还可以通过该连接接收来自服务器的watcher事件通知。一个session的创建流程如下:


1.初始化Zookeeper对象;

2.设置会话默认watcher;

3.构造zookeeper服务器地址列表管理器HostProvider;

4.创建并初始化客户端网络连接器ClientCnxn(两个核心队列outgoingQueue和pendingQueue);

5.初始化SendThread(客户端服务端之间所有IO)和EventThread(客户端事件处理);

6.启动SendThread和EventThread

7.获取一个zookeeper服务器地址;

8.创建TCP连接;

9.构造ConnectRequest请求(通过SendThread放到outgoingQueue);

10.发送请求(ClientCnxn从outgoingQueue中取出,序列化向服务端发送);

11.接收服务端响应;

12.处理Response(反序列化获取sessionID);

13.连接成功;

14.生成SyncConnected-None事件,传递给EventThread;

15.查询watcher,取出步骤2中的watcher放到EventThread队列中;

16.处理事件;


session有如下4个基本属性:


sessionID:会话唯一标示;


Timeout:会话超时时间;


Ticktime:下次会话超时时间点(13位long型,相当于当前时间加上TImeout);


isClosing:是否已被关闭;


zookeeper对session采用分桶管理策略,根据下次超时时间点(Ticktime)进行分配。


znode


znode可分为持久节点临时节点两类,同时支持对下一级子节点的创建顺序进行维护。


持久节点是一旦被创建,除非主动进行znode移除,否则将一直保存在zookeeper上。


临时节点的声明周期和客户端会话绑定,一旦客户端会话失效,那么客户端所创建的所有临时节点都会被移除。


对于每个zonode,zookeeper会为其维护一个stat的数据结构,结构如下:



我们看到stat记录了znode的三个版本参数,分别为version(znode版本)、cversion(znode子节点的版本)和aversion(znode的acl版本)。在客户端对znode节点进行修改操作时,zookeeper是用过乐观锁来实现版本控制的,即先比对当前版本version和操作的版本是否一致,如不一致则拒接,并抛出BadVersionException异常。


watcher


watcher(事件监听器)是zookeeper中的一个重要特性,允许用户在指定节点上注册一些watcher,在一些特定事件触发的时候zookeeper服务端会将事件通知到感兴趣的客户端,该机制是zookeeper实现分布式协调服务的重要特性。


watcher通知状态和事件类型:




watcher的工作机制,大体上分为三个阶段:客户端注册watcher、服务端处理watcher和客户端回调watcher。客户端先将watcher对象转交给ZKWatchManager,并最终保存到一个Map<String , Set<Watcher>>类型的对象dataWatches中,将数据节点路径和watcher对象映射起来。事件发生时,服务端会将通知状态(KeeperState)、事件类型(EventType)以及节点路径(Path)封装成一个WatchedEvent对象,然后从watcherTable中取出对应的watcher并删除,调用process()接口触发watcher。客户端接收到WatchedEvent对象,反序列化并处理。


需要注意的一点是,watcher事件有一次性的特点。即一旦一个watcher事件触发,zookeeper就会将其移除,因此开发人员需要注意是watcher需要反复注册。不过值得庆幸的是在实际开发中我们不需要直接编写相关代码,zookeeper的两大客户端zkClient和curator都已近帮我们实现自动再注册了。


ACL


acl(Access Control Lists)策略用来进行权限控制,zookeeper支持如下4种权限模式


IP:通过IP地址来进行权限控制;


Digest:通过"username:password"权限标示来进行权限控制;


World:对所有用户开放权限,可看做特殊的Digest模式"world:anyone";


Super:超级管理员权限,可对任何权限控制的节点操作;


其中中定义了如下5种权限


create:创建子节点权限

read:获取节点数据和子节点列表权限

write:更新节点数据权限

delete:删除子节点权限

admin:设置节点acl权限



TXID


对于来自客户端的每个更新请求,zookeeper都会分配一个全局唯一的递增编号,这个编号反应了所有事务操作的先后顺序,这就是txid。


TXID是一个64位的数字,其中低32位可看做是一个简单的单调递增的计数器,针对客户端的每个事务请求,leader服务器在产生一个新的事务proposal的时候,都会对该计数器进行加1操作;而高32位则代表了leader周期epoch的编号,每当选举产生一个新的leader服务器,就会从这个leader服务器上取出其本地日志中最大事务proposal的ZXID,并从该ZXID中解析出对应的epoch值,然后再对其进行加1操作,之后就会依次编号作为新的epoch,并将低32位置0来生成新的ZXID。zookeeper通过epoch编号来区分leader周期变化,能有效地避免不同的leader服务器错误使用相同的ZXID编号提出不一样的事务。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值