【Zookeeper学习】4.Zookeeper基础


1 简介

Zookeeper是由雅虎创建,Zookeeper并没有直接采用Paxos算法,而是采用了一种被称为ZAB(Zookeeper Atomic Broadcast)的一致性协议

Zookeeper是一个典型的分布式数据一致性的解决方案,分布式应用程序可以基于它实现诸如数据发布/订阅负载均衡命名服务分布式协调/通知集群管理Master选举分布式锁分布式队列等功能。

2 Zookeeper基本概念

2.1 集群角色

Leader:Leader服务器为客户端提供读写服务
Follower:Follower为客户端提供读服务
Observer:Observer为客户端提供读服务,不参与选举Leader,不参与事务投票,不影响写性能提高集群的读性能。

2.2 会话(Session)

Session是指客户端会话,是客户端连接服务端的一个TCP长连接。服务端的Watch事件通知也是通过该TCP连接

2.3 数据节点(Znode)

Zookeeper将所有的数据存储在内存中,数据模型是一棵树(Znode Tree),由斜杆进行分割的路径,就是一个Znode,每个Znode上都会保存自己的数据内容,同时还会保存一些列的属性信息。

Znode结构

在Zookeeper中,Znode分为持久节点临时节点,持久节点是指一旦创建,除非主动删除,否则这个Znode会一直在Zookeeper中,临时节点它的生命周期是跟会话绑定,一旦客户端会话失效,临时节点将会删除。另外,Zookeeper可以为每个节点添加SEQUENTIAL属性,一旦有这个属性,那么节点就是一个有序节点

  • 持久节点(PERSISTENT)(默认):在该数据节点创建后,就一直存在与Zookeeper服务器上,直到有删除操作主动清除这个节点。不会因为创建该节点的客户端会话失效而消失;
  • 持久顺序节点(PERSISTENT_SEQUENTIAL):在ZK中每个父节点会为他的第一级子节点维护一份顺序,用于记录每个子节点创建的先后顺序
  • 临时节点(EPHEMERAL):和持久节点不同,临时节点的生命周期和客户端会话绑定。如果客户端会话失效,那么这个节点就会自动被清除掉。注意,这里提到的是会话失效,而非TCP连接断开
  • 临时顺序节点(EPHEMERAL_SEQUENTIAL)

2.4 版本

Zookeeper会对每一个Znode维护一个Stat的数据结构,Stat中记录了Znode的三个数据版本,分别是:

  • version(当前Znode的版本
  • cversion(当前Znode子节点的版本
  • aversion(当前Znode的ACL版本
Znode stat

2.5 Watcher

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

  • 特点
    • 一次性:
      • 只触发一次watches;
      • 先注册再触发
    • 异步:
      • watcher event 异步发送 watcher通知事件,即:从 server 发送到 client异步的
      • 只能保证最终的一致性
    • 轻量级事件:
      • Watcher 通知非常简单,只会告诉客户端发生了事件,而不会说明事件的具体内容;
      • 客户端向服务端注册 Watcher 的时候,并不会把客户端真实的 Watcher 对象实体传递到服务端,仅仅是在客户端请求中使用 boolean 类型属性进行了标记。
    • 客户端串行执行:客户端 Watcher 回调的过程是一个串行同步的过程。

2.5.1 工作机制

  • 客户端注册 watcher
    • 调用 getData()/getChildren()/exist()三个 API,传入 Watcher 对象
    • 标记请求 request,封装 WatcherWatchRegistration
    • 封装成 Packet 对象,向服务端发送 request
    • 收到服务端响应后,将 Watcher 注册ZKWatcherManager 中进行管理;
    • 请求返回,完成注册。
  • 服务端处理 watcher
    • 服务端接收 Watcher 并存储:接收到客户端请求,处理请求判断是否需要注册 Watcher,需要的话将数据节点的节点路径和 ServerCnxn(ServerCnxn 代表一个客户端和服务端的连接,实现了 Watcherprocess 接口,此时可以看成一个 Watcher 对象)存储在WatcherManagerWatchTablewatch2Paths 中去。
    • Watcher 触发:以服务端接收到 setData() 事务请求触发 NodeDataChanged 事件为例:
      • 封装 WatchedEvent:将通知状态(SyncConnected)、事件类型(NodeDataChanged)以及节点路径封装成一个 WatchedEvent 对象
      • 查询 Watcher:从 WatchTable 中根据节点路径查找 Watcher
      • 没找到:说明没有客户端在该数据节点上注册Watcher
      • 找到:提取并从 WatchTableWatch2Paths删除对应 Watcher(从这里可以看出 Watcher 在服务端是一次性的,触发一次就失效了)
    • 调用 process 方法来触发 Watcher:这里 process 主要就是通过 ServerCnxn 对应的 TCP 连接发送 Watcher 事件通知
  • 客户端回调 watcher
    • 客户端 SendThread 线程接收事件通知,交由 EventThread 线程回调 Watcher
    • 客户端的 Watcher 机制同样是一次性的,一旦被触发后,该 Watcher 就失效了。
Watcher流程

文章作者: Kezade
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Kezade !
评论
  目录