SpringCloud 14 —— 注册中心之Zookeeper

Zookeeper 简介

ZooKeeper是一个开源的分布式协调服务,由雅虎创建,是GoogleChubby的开源实现。ZooKeeper的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。

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

  • 顺序一致性
    从同一个客户端发起的事务请求,最终将会严格按照其发起顺序被应用到ZooKeeper中。

  • 原子性
    所有事务请求的结果在集群中所有机器上的应用情况是一致的,也就是说要么整个集群所有集群都成功应用了某一个事务,要么都没有应用,一定不会出现集群中部分机器应用了该事务,而另外一部分没有应用的情况。

  • 单一视图
    无论客户端连接的是哪个ZooKeeper服务器,其看到的服务端数据模型都是一致的。

  • 可靠性
    一旦服务端成功地应用了一个事务,并完成对客户端的响应,那么该事务所引起的服务端状态变更将会被一直保留下来,除非有另一个事务又对其进行了变更。

  • 实时性
    通常人们看到实时性的第一反应是,一旦一个事务被成功应用,那么客户端能够立即从服务端上读取到这个事务变更后的最新数据状态。这里需要注意的是,ZooKeeper仅仅保证在一定的时间段内,客户端最终一定能够从服务端上读取到最新的数据状态

Zookeeper 中的角色( Role )

在ZooKeeper中,有三种角色,分别是:

Leader
Follower
Observer

一个ZooKeeper集群同一时刻只会有一个Leader,其他都是Follower或Observer。

ZooKeeper配置很简单,每个节点的配置文件(zoo.cfg)都是一样的,只有myid文件不一样。myid的值必须是zoo.cfg中server.{数值}的{数值}部分。

maxClientCnxns=0
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
dataDir=/opt/zookeeper/data
# the port at which the clients will connect
clientPort=2181
# the directory where the transaction logs are stored.
dataLogDir=/opt/zookeeper/logs
server.1=192.168.0.167:2888:3888
server.2=192.168.0.168:2888:3888
server.3=192.168.0.169:2888:3888
minSessionTimeout=4000
maxSessionTimeout=100000

通过执行zookeeper-server status可以看当前节点的ZooKeeper是什么角色

# zookeeper-server status
JMX enabled by default
Using config: /etc/zookeeper/conf/zoo.cfg
Mode: leader

ZooKeeper默认只有Leader和Follower两种角色,没有Observer角色。Zookeeper为了满足过半选举,集群最少需要3台机器

  1. 为了使用Observer模式,在任何想变成Observer的节点的配置文件中加入:peerType=observer ,并在所有server的配置文件中,配置成Observer模式的server的那行配置追加:observer,例如: server.1:localhost:2888:3888:observer
  2. ZooKeeper集群的所有机器通过一个Leader选举过程来选定一台被称为Leader的机器,Leader服务器为客户端提供读和写服务。
  3. Follower和Observer都能提供读服务,不能提供写服务。两者唯一的区别在于,Observer机器不参与Leader选举过程,也不参与写操作的过半写成功策略,因此Observer可以在不影响写性能的情况下提升集群的读性能

会话(Session)

Session是指客户端会话,在ZooKeeper中,一个客户端连接是指客户端和ZooKeeper服务器之间的TCP长连接。ZooKeeper对外的服务端口默认是2181,客户端启动时,首先会与服务器建立一个TCP连接,从第一次连接建立开始,客户端会话的生命周期也开始了,通过这个连接,客户端能够通过心跳检测和服务器保持有效的会话,也能够向ZooKeeper服务器发送请求并接受响应,同时还能通过该连接接收来自服务器的Watch事件通知。Session的SessionTimeout值用来设置一个客户端会话的超时时间。当由于服务器压力太大、网络故障或是客户端主动断开连接等各种原因导致客户端连接断开时,只要在SessionTimeout规定的时间内能够重新连接上集群中任意一台服务器,之前创建的会话仍然有效。

数据节点(ZNode)

在ZooKeeper中,ZNode可以分为持久节点和临时节点两类

ZooKeeper中的数据节点是指数据模型中的数据单元,称为ZNode
ZooKeeper将所有数据存储在内存中,数据模型是一棵树(ZNode Tree),由斜杠(/)进行分割的路径,就是一个ZNode,如/canal/position,其中canal和position都是ZNode。每个ZNode上都会保存自己的数据内容,同时会保存一系列属性信息。

持久节点: 指一旦这个ZNode被创建了,除非主动进行ZNode的移除操作,否则这个ZNode将一直保存在ZooKeeper上

临时节点: 临时节点的生命周期跟客户端会话绑定,一旦客户端会话失效,那么这个客户端创建的所有临时节点都会被移除。另外,ZooKeeper还允许用户为每个节点添加一个特殊的属性:SEQUENTIAL。一旦节点被标记上这个属性,那么在这个节点被创建的时候,ZooKeeper就会自动在其节点后面追加上一个整型数字,这个整型数字是一个由父节点维护的自增数字

版本( Version )

ZooKeeper的每个ZNode上都会存储数据,对应于每个ZNode,ZooKeeper都会为其维护一个叫作Stat的数据结构,Stat中记录了这个ZNode的三个数据版本,分别是version(当前ZNode的版本)、cversion(当前ZNode子节点的版本)和aversion(当前ZNode的ACL版本)

状态信息( Status)

每个ZNode除了存储数据内容之外,还存储了ZNode本身的一些状态信息。用 get 命令可以同时获得某个ZNode的内容和状态信息

在ZooKeeper中,version属性是用来实现乐观锁机制中的写入校验(保证分布式数据原子性操作)

事务操作( Transaction )

能改变ZooKeeper服务器状态的操作称为事务操作。一般包括数据节点创建与删除、数据内容更新和客户端会话创建与失效等操作。对应每一个事务请求,ZooKeeper都会为其分配一个全局唯一的事务ID,用ZXID表示,通常是一个64位的数字。每一个ZXID对应一次更新操作,从这些ZXID中可以间接地识别出ZooKeeper处理这些事务操作请求的全局顺序

Watcher

Watcher(事件监听器),是ZooKeeper中一个很重要的特性。ZooKeeper允许用户在指定节点上注册一些Watcher,并且在一些特定事件触发的时候,ZooKeeper服务端会将事件通知到感兴趣的客户端上去。

ACL

ZooKeeper采用ACL(Access Control Lists)策略来进行权限控制。ZooKeeper定义了如下5种权限。

  • CREATE: 创建子节点的权限。
  • READ: 获取节点数据和子节点列表的权限。
  • WRITE:更新节点数据的权限。
  • DELETE: 删除子节点的权限。
  • ADMIN: 设置节点ACL的权限。

注意:CREATE 和 DELETE 都是针对子节点的权限控制。

ZAB协议

ZAB协议的核心是定义了对应那些会改变ZooKeeper服务器数据状态的事务请求的处理方式,所有事务请求必须由一个全局唯一的服务器来协调处理,这样的服务器被称为Leader服务器,而剩下的其他服务器则成为Follower服务器。Leader服务器负责将一个客户端事务请求转换成一个事务Proposal(提案)并将该Proposal分发给集群中所有的Follower服务器。之后Leader服务器需要等待所有Follower服务器的反馈,一旦超过半数的Follower服务器进行了正确的反馈后,Leader就会再次向所有的Follower服务器分发Commit消息,要求对刚才的Proposal进行提交

ZAB协议包括两种基本的模式,分别是崩溃恢复和消息广播。在整个ZooKeeper集群启动过程中,或是当Leader服务器出现网络中断、崩溃退出与重启等异常情况时,ZAB协议就会进入恢复模式并选举产生新的Leader服务器。当选举产生了新的Leader服务器,同时集群中有过半的机器与该Leader服务器完成了状态同步之后,ZAB协议就会退出恢复模式。其中,状态同步是指数据同步,用来保证集群中存在过半的机器能够和Leader服务器的数据状态保持一致。

崩溃恢复模式包括两个阶段:Leader选举和数据同步。

当集群中有过半的Follower服务器完成了和Leader服务器的状态同步,那么整个集群就可以进入消息广播模式了。

Zookeeper 和 Eu