在分布式系统中,为了保证应用的高可用,通常会为其搭建集群环境。
Zookeeper集群架构
对于集群环境,通常都会有主从节点。有主从节点就有角色之分。
Zookeeper集群角色
- 客户端(Client):请求发起方。
- 领导者(Leader):事务请求(写操作)的唯一调度者和处理者,保证集群事务处理的顺序性;集群内部各个服务器的调度者。对于create、setData、delete等有写操作的请求,则要统一转发给leader处理,leader需要决定编号、执行操作,这个过程称为事务。
- 跟随者(Follower):处理客户端非事务(读操作)请求(可以直接响应),转发事务请求给Leader;参与集群Leader选举投票。
- 观察者(Observer):对于非事务请求可以独立处理(读操作),对于事务性请求会转发给leader处理。Observer 节点接收来自 leade r的 inform 信息,更新自己的本地存储,不参与提交和选举投票。通常在不影响集群事务处理能力的前提下提升集群的非事务处理能力。
Follower 和 Observer 统称为学习者(Learner)。
Observer应用场景:
- 提升集群的读性能。因为Observer和不参与提交和选举的投票过程,所以可以通过往集群里面添加 Observer 节点来提高整个集群的读性能。
- 跨数据中心部署。 比如需要部署一个北京和香港两地都可以使用的 Zookeeper集群服务,并且要求北京和香港客户的读请求延迟都很低。解决方案就是把香港的节点都设置为Observer。
Zookeeper集群架构
leader节点可以处理读写请求,follower只可以处理读请求。follower在接到写请求时会把写请求转发给leader来处理。
Zookeepr集群 Leader 选举原理
Zookeeper 的 Leader 选举存在两个阶段,一个是服务器启动时 Leader 选举,另一个是运行过程中 Leader 服务器宕机。
在分析选举原理前,先介绍几个重要的参数:
- 服务器 ID(myid):编号越大在选举算法中权重越大。
- 事务 ID(zxid):值越大说明数据越新,权重越大。
- 逻辑时钟(epoch-logicalclock):同一轮投票过程中的逻辑时钟值是相同的,每投完一次值会增加
Zookeeper 选举状态
- LOOKING: 竞选状态。
- FOLLOWING: 随从状态,同步 leader 状态,参与投票。
- OBSERVING: 观察状态,同步 leader 状态,不参与投票。
- LEADING: 领导者状态。
服务器启动时的 leader 选举
每个节点启动的时候都 LOOKING 观望状态,接下来就开始进行选举主流程。这里选取三台机器组成的集群为例。第一台服务器 server1启动时,无法进行 leader 选举,当第二台服务器 server2 启动时,两台机器可以相互通信,进入 leader 选举过程。
- 每台 server 发出一个投票,由于是初始情况,server1 和 server2 都将自己作为 leader 服务器进行投票,每次投票包含所推举的服务器myid、zxid、epoch,使用(myid,zxid)表示,此时 server1 投票为(1,0),server2 投票为(2,0),然后将各自投票发送给集群中其他机器。
- 接收来自各个服务器的投票。集群中的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票(epoch)、是否来自 LOOKING 状态的服务器。
- 分别处理投票。针对每一次投票,服务器都需要将其他服务器的投票和自己的投票进行对比,对比规则如下:a. 优先比较 epoch。b. 检查 zxid,zxid 比较大的服务器优先作为 leader。c. 如果 zxid 相同,那么就比较 myid,myid 较大的服务器作为 leader 服务器。
- 统计投票。每次投票后,服务器统计投票信息,判断是都有过半机器接收到相同的投票信息。server1、server2 都统计出集群中有两台机器接受了(2,0)的投票信息,此时已经选出了 server2 为 leader 节点。
- 改变服务器状态。一旦确定了 leader,每个服务器响应更新自己的状态,如果是 follower,那么就变更为 FOLLOWING,如果是 Leader,变更为 LEADING。此时 server3继续启动,直接加入变更自己为 FOLLOWING。
运行过程中的 leader 选举
当集群中 leader 服务器出现宕机或者不可用情况时,整个集群无法对外提供服务,进入新一轮的 leader 选举。
- 变更状态。Leader 宕机后,其他非 Oberver 服务器将自身服务器状态变更为 LOOKING。
- 每个 server 发出一个投票。在运行期间,每个服务器上 zxid 可能不同。
- 处理投票。规则同启动过程。
- 统计投票。与启动过程相同。
- 改变服务器状态。与启动过程相同。
Zookeeper集群环境准备
这里我们准备三节点的 Zookeeper 集群,因此需要三台虚拟机,可以直接克隆单节点的虚拟机直接使用。三台虚拟机的 IP :192.168.31.163、192.168.31.178、192.168.31.214。
也可以在一台虚拟机上使用不同端口搭建伪集群。
Zookeeper集群创建
在 Zookeeper 集群中,每个节点需要一个唯一标记,这个唯一标识要求是自然数,且唯一标识保存的位置是:数据存储目录的 myid 文件中,其中数据存储目录为 zoo.cfg 中配置的参数。
创建 myid 文件,配置服务器编号
比如,这里三台虚拟机的 Zookeeper 节点的唯一标记分别为1、2、3。
集群配置
分别修改三个节点的 zoo.conf 配置文件,添加如下集群配置。
server.A=B:C:D
- A 是一个数字,表示这个是第几号服务器; 集群模式下配置一个文件 myid,这个文件在 dataDir 目录下,这个文件里面有一个数据 就是 A 的值,Zookeeper 启动时读取此文件,拿到里面的数据与 zoo.cfg 里面的配置信息比较从而判断到底是哪个server。
- B 是这个服务器的地址;
- C 是这个服务器Follower与集群中的Leader服务器交换信息的端口;
- D 是万一集群中的Leader服务器挂了,需要一个端口来重新进行选举,选出一个新的Leader,而这个端口就是用来执行选举时服务器相互通信的端口。
启动 Zookeeper server集群
启动前需要关闭防火墙(生产环境需要打开对应端口)。