ZooKeeper 5:集群模式

prev:ZooKeeper 4:会话处理与其源码分析

ZooKeeper作为目前开源技术体系的无可替代的基础组件,首先要保证自身的高可用,也就是对于部分服务下线要有一定的容忍能力,不能说ZooKeeper突然挂了所有的服务都跟着寄了。
为保证高可用,ZooKeeper提供了集群模式,或者说是Master/Slave架构,防止单点故障影响整个服务。

角色与职责

在这里插入图片描述
图源:ZooKeeper 集群

角色职责
Leader可以处理读写请求这里的读写请求来自Follower和Observer;事务的发起和决议;更新系统状态
Follower处理读请求,将写请求转发给Leader;参与Leader发起的事务处理,负责本节点的数据变更和事务提交;参与Leader选举;同步Leader状态(保持心跳连接)
Observer处理读请求,将写请求转发给Leader ;不参与Leader发起的事务处理;不参与Leader选举 ;同步Leader状态(保持心跳连接)

为什么要引入Observer(ZK 3.3.0)?

  1. 在不影响写性能的前提下,提升读操作的性能和吞吐量
    ① Follower数量越多,写操作的性能越差,吞吐量越小
    ② Observer不参与事务处理,数量再多也不影响集群的写性能
    ③ Observer不参与选主和事务处理,即使宕机也不影响集群的可用性
  2. 提升集群的可扩展性,以及大规模访问的承载能力
  3. 跨中心部署Observer ,为本地读请求提供快速响应
    ① Leader和Follower部署在一个中心,很大程度上降低了网络延时对写性能的影响
    ②由于Observer要转发写请求和同步Leader状态,所以跨中心部署并不能彻底消除网络延时
    例如:阿里开源的跨机房同步系统Otter

仲裁机制

Leader和Follower遵循Quorum仲裁机制(过半策略),也就是说,若Leader+Follwer的数量为m,则Quorum = m/2 + 1,只有投票数大于等于Quorum,事务和选举才判定成功。
因此官方文档强烈建议使用奇数台服务器作为ZooKeeper集群,这样的话在不影响事务处理的前提下,最多可容忍n台宕机。
举个例子:
对于节点数为5和6的两个集群:

  • 二者都最多容忍2台宕机,所以容灾能力相同;
  • 前者的Quorum数为3,后者为4,前者更小,事务处理和选举的效率更高

为什么采用过半策略

防止集群脑裂:对于一个集群,通常多台机器会部署在不同机房,来提高这个集群的可用性。保证可用性的同时,会发生一种机房间网络线路故障,导致机房间网络不通,而集群被割裂成几个小集群。这时候子集群各自选主导致“脑裂”的情况,会导致数据一致性问题。ZooKeeper的过半机制导致不可能产生 2 个leader,因为少于等于一半是不可能产生leader的,这就使得不论机房的机器如何分配都不可能发生脑裂。

状态和选举

服务器的四种状态:

  • LOOKING:寻找Leader状态,表示当前集群没有Leader,需要进行选举
  • LEADING:领导者状态,当前角色为Leader
  • FOLLOWING:跟随者状态,Leader选举已完成,当前角色为Follower
  • OBSERVING:观察者状态,当前角色为Observer,不参与选举和写事务

选举的原则:选择能力强,数据新的节点作为Leader

选票

选票的数据结构:(sid, zxid),sid为服务器id,zxid为当前服务器的最大事务id
选票的比较规则: ①zxid大的胜出;②若zxid相等,则sid大的胜出

从选票也可以看出,zxid代表了这个机器上的ZooKeeper服务是不是最新的,否则要看机器id的大小了。

启动期间的Leader选举

在这里插入图片描述
如上图所示,在启动时期Leader选举

  1. 启动ZK1并发起投票。投票(1,0)给自己,发现未过半数,选不出Leader
  2. 启动ZK2
    (1)发起第1轮投票。ZK1和ZK2分别投票给自己和其他服务器,ZK1为(1,0),ZK2为(2,0)
    (2)统计第1轮投票。ZK1对投给自己的票(1,0)与ZK2发过来的票(2,0)进行比较,根据比较规则,(2,0)胜出,ZK1更新自己的投票为(2,0);以此类推,ZK2保持自己的投票(2,0)不变。至此,ZK1和ZK2都给ZK2投了1票,但未过半数,选不出Leader
    (1)发起第2轮投票。 ZK1和ZK2分别投票给自己和其他服务器,ZK1为(2,0),ZK2为(2,0)
    (2)统计第2轮投票。 ZK1和ZK2都有2票(2,0),已超过半数,ZK2当选Leader
    (3)更改Server状态。将ZK2的状态改为LEADING,ZK1的状态改为FOLLOWING
  3. 启动ZK3。发现已有Leader,不再选举,直接从LOOKING改为FOLLOWING

运行期间的Leader选举

在这里插入图片描述
这里也贯穿着选举思想:能力强,数据新
如上图所示:

  1. 某时刻,之前的Leader ZK2挂了,此时需要一台新的Leader,ZK1和ZK3的状态为Looking
  2. 第一轮投票
    (1)发起第1轮投票。ZK1和ZK3分别投票给自己和其他服务器,ZK1为(1,124),ZK3为(3,123)
    (2)统计第1轮投票。ZK1对投给自己的票(1,124)与ZK2发过来的票(3,123)进行比较,根据比较规则,(1,124)胜出,因为ZK1上的数据事务id大,说明数据比较新,ZK3更新自己的投票为(1,124);以此类推,ZK1保持自己的投票(1,124)不变。至此,ZK1和ZK3都给ZK2投了1票,但未过半数,选不出Leader
  3. 第二轮投票
    (1)发起第2轮投票。 ZK1和ZK3别投票给自己和其他服务器,ZK1为(1,124),ZK3为(1,124)
    (2)统计第2轮投票。 ZK1和ZK3都统计到有2票(1,124),已超过半数,ZK1当选Leader
    (3)更改Server状态。将ZK1的状态改为LEADING,ZK3的状态改为FOLLOWING

配置集群模式

环境:Mac,ZooKeeper3.8
仍然继续第一部分的安装。
首先复制出来三个ZooKeeper的目录,分别命名为:zookeeper-01,zookeeper-02,zookeeper-03
修改配置文件/conf/zoo.cfg

# zk1
dataDir=/usr/local/software/zookeeper-01/data
dataLogDir=/usr/local/software/zookeeper-01/log
clientPort=2181
server.1=127.0.0.1:2887:3887
server.2=127.0.0.1:2888:3888
server.3=127.0.0.1:2889:3889
# zk2
dataDir=/usr/local/software/zookeeper-02/data
dataLogDir=/usr/local/software/zookeeper-02/log
clientPort=2182
server.1=127.0.0.1:2887:3887
server.2=127.0.0.1:2888:3888
server.3=127.0.0.1:2889:3889
# zk3
dataDir=/usr/local/software/zookeeper-03/data
dataLogDir=/usr/local/software/zookeeper-03/log
clientPort=2183
server.1=127.0.0.1:2887:3887
server.2=127.0.0.1:2888:3888
server.3=127.0.0.1:2889:3889

在data下创建myid文件并写入1,2,3:

# zk1
vim data/myid
# 输入1,wq
# zk2
vim data/myid
# 输入2,wq
# zk3
vim data/myid
# 输入3,wq

运行:

/zookeeper-01/bin/zkServer.sh start
/zookeeper-01/bin/zkServer.sh start
/zookeeper-01/bin/zkServer.sh start

检查服务状态:

/zookeeper-01/bin/zkServer.sh status
Using config: /usr/local/software/zookeeper-01/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: follower

/zookeeper-02/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /usr/local/software/zookeeper-02/bin/../conf/zoo.cfg
Client port found: 2182. Client address: localhost. Client SSL: false.
Mode: follower

/zookeeper-03/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /usr/local/software/zookeeper-03/bin/../conf/zoo.cfg
Client port found: 2183. Client address: localhost. Client SSL: false.
Mode: leader

参考

ZooKeeper在Mac上集群部署
ZooKeeper 集群
大数据理论与实践2 分布式协调服务Zookeeper

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值