搞懂分布式技术3:初探分布式协调服务zookeeper
1.Zookeepr是什么
Zookeeper是一个典型的分布式数据一致性的解决方案,分布式应用程序可以基于它实现诸如数据发布/订阅,负载均衡,命名服务,分布式协调/通知。集群管理,Master选举,分布式锁和分布式队列等功能。
2.zookeeper可以保证的分布式一致性
a.顺序一致性
从一个客户端发起的事务请求,最终将会严格地按照其发起顺序被应用到zookeeper中去
b.原子性
所有事务请求的处理结果在整个集群中所有机器上的应用情况是一致的。
c.单一视图
任意客户端看到的服务器数据模型都是一致的
d.可靠性
一旦服务成功的应用了一个事务,并完成对客户端响应,那么该事务所引起的服务端状态变更将会被一直保留下来,除非另一个事务又对其进行变更
e.实时性
Zookeeper仅仅保证在一定时间内,客户端最终一定能够从服务器上读取到最新的数据状态。
3.zookeeper的设计目标
目标一:简单的数据模型
Zookeeper可以让分布式程序能通过一个共享的、树型结构的名字空间来进行相互协调(和windows系统的文件结构相同,是有一系列的ZNode节点之间的层级关系构成)
目标二:可构建集群
3到5台机器就可以组成一个可用的zookeeper集群
目标三:顺序访问
对于来自客户端的每一个更新请求,zookeeper都会分配一个全局唯一的递增编号,这个编号反应了所有事务操作的先后顺序。
目标四:高性能
Zookeeper把所有的节点数据都存储在内存中(提高了服务器吞吐、减少了延迟),并直接服务于客户端所有非事务请求,因此尤其适用于以读操作为主的应用场景。
4.zookeeper的基本概念
集群角色
在 zookeeper 集群中,各个节点总共有三种角色,分别是:leader,follower,observer
而不是Master/slave(主备机模式)
会话(session)
Session是指客户端的会话,Zookeeper对外的端口默认2181,可以通过sessionTimeout设置会话超时时间,由于服务器压力、网络原因或客户端主动断开等原因使客户端链接断开,只要在sessionTimeout规定时间内就能够重新链接上集群的任意一台服务器,之前的会话仍然有效。
数据节点(ZNode)
ZNode保存在zookeeper内存中,数据模型是一个树(ZNode Tree)由(/)进行分割路径
版本
每个节点都会存储数据,zookeeper会为其维护一个Stat的数据结构,其中包括三个版本信息
cversion= 0 子节点的版本号
aclVersion= 0 表示acl的版本号,修改节点权限
dataVersion= 1 表示的是当前节点数据的版本号
Watcher
Watcher(事件监听器),非常重要的特性。Zookeeper允许用户在指点节点上注册一些Watcher,并在一些特定的事件触发的时候,通知客户端(可实现分布式协调服务)
Zookeeper的Watcher VS JVM?
从某种角度来说,可以这样对比(个人看法,可以讨论),ZooKeeper对等于JVM,ZooKeeper包含状态对象(ZNode)和分布式进程的底层执行引擎Zab,而JVM内部包含堆(多线程共享的大量对象存放区域)和多线程执行正确性约束规范JMM(Java内存模型),JMM确保了多线程的执行顺序是正确的。Zab协议使得ZooKeeper的内部修改状态操作直接是有序串行的,而JVM内部则是乱序并行的,需要添加额外的机制才能保证时序(内存屏障、处理器原子指令),而状态读取时,JVM和ZooKeeper都存在直接读取时读到旧数据,但ZooKeeper有Watch机制使得响应式读取更高效,而JVM只能使用底层的内存屏障刷新共享状态,以便其他线程再次读取时获得正确的新数据。
ZooKeeper提供的接口使得所有的分布式进程的执行都是异步非阻塞的(WaitFree算法),内部是基于Version的CAS操作,而JVM提供了阻塞的和非阻塞的多种接口,有Synchronized、Volatile、AtomicOperations。基于接口之上构建线程或分布式进程之间更复杂的同步或协调功能时,Java并发库直接提供了闭锁、循环栅栏、信号量等同步工具以及基础的抽象队列同步器,而ZooKeeper则需要用户基于接口自行构建各种分布式协调功能(分布式锁、分布式发布订阅、集群成员关系管理)
对比:
ZooKeeper JVM
共享状态对象: ZNode 堆中对象
底层执行模式: Zab顺序执行 多处理器并发执行(内存屏障、原子机器指令)
API接口: Get、Watch_Get、Cas_Set、Exist Synchronized、volatile、final、Atomic
协调或同步功能: 分布式发布订阅、锁、读写锁 并发库同步工具、基于抽象队列同步器构建的同步组件
Zookepper的Watcher架构?
客户端先向ZooKeeper服务端成功注册想要监听的节点状态,同时客户端本地会存储该监听器相关的信息在WatchManager中,当ZooKeeper服务端监听的数据状态发生变化时,ZooKeeper就会主动通知发送相应事件信息给相关会话客户端,客户端就会在本地响应式的回调相关Watcher的Handler
Zookeeper的Watcher机制主要包括客户端线程、客户端WatcherManager、Zookeeper服务器三部分。客户端在向Zookeeper服务器注册的同时,会将Watcher对象存储在客户端的WatcherManager当中。当Zookeeper服务器触发Watcher事件后,会向客户端发送通知,客户端线程从WatcherManager中取出对应的Watcher对象来执行回调逻辑。
Zookepper的Watcher的特性?
1.Watch是一次性的,每次都需要重新注册,并且客户端在会话异常结束时不会收到任何通知,而快速重连接时仍不影响接收通知。
2.Watch的回调执行都是顺序执行的,并且客户端在没有收到关注数据的变化事件通知之前是不会看到最新的数据,另外需要注意不要在Watch回调逻辑中阻塞整个客户端的Watch回调
3.Watch是轻量级的,WatchEvent是最小的通信单元,结构上只包含通知状态、事件类型和节点路径。ZooKeeper服务端只会通知客户端发生了什么,并不会告诉具体内容。
ACL
access control list
权限控制
CREATE:创建子节点的权限
READ:获取子节点数据和子节点列表的权限
WRITE:更新节点数据的权限
DELETE:删除节点数据的权限
ADMIN:设置节点ACL的权限