zookeeper集群注意点


本文记录了学习过程中的部分知识点,部分知识点自己也没看懂。 需要保持怀疑的态度

一 Zookeeper

1.1 顺序一致性

  1. zookeeper本质也是最终一致性,并不能保证每个follower节点上的数据都是新的。
  2. 一致性也是指集群中大部分节点的数据保持一致(一致性这个次都被用烂了!各种解释都有😭

问题:
zookeeper客户端在timeout之内重连成功(连接到了其他follower节点)。有没有可能看到更旧的数据?

在知乎看到回答,clinet会持有之前最大的zxid。如果连到了一台旧的节点上,会自动切换到其他节点

1.2 响应成功的数据一定存在

如果对集群中的leader节点发出写请求,如果响应给客户端成功。那么leader必然已经接收到了一半以上节点的ack。那么leader不挂,最终一致性会保证数据在所有节点都存在。
如果leader挂了,那么也能肯定新选举的节点必然有响应成功的数据。

1.3 leader会一直等半数以上的ack

这个是我自己得出的结论,没找到明确这么说的文章.否则假如没等到就响应失败,那么此时重新选举。本次提交的写请求可能会被生效

其实感觉这段话就是印证了我的观点
在这里插入图片描述
只要leader发出了proposal,那么正常情况是没有follower会说:我执行不了,会报错之类的(和数据库不一样

1.4 奔溃恢复要求

ZAB协议崩溃恢复要求满足如下2个要求:

  1. 确保已经被leader提交的proposal必须最终被所有的follower服务器提交。 (这个两个大多数肯定有交集可以确保
  2. 确保丢弃已经被leader出的但是没有被提交的proposal。(这句话感觉不太准确,也有可能是我理解问题。因为在我理解中,如果leader还没提交,那么proposal可能会在新的leader中,也有可能不在)

其他文章对第二点的解读
在这里插入图片描述

1.5 验证

1.3和1.4 的想法也可以通过该文对照:ZAB
在这里插入图片描述

其实只要leader将proposal发送到了一个follower(这个follower没挂,不到半数)。那么这个leader奔溃后,这个follower就会凭着最大的zxid当选leader。那么该事务就会生效

二 Paxos

2.1 介绍

paxos的文章网上很多,我这里只记录个人的理解。具体的细节,可以看其他文章。
刚开始我看了很多篇文章,但就是感觉看不懂。设置连paxos到底想干嘛,解决了什么问题都看不懂😭

问题描述
Lesile Lamport,Latex 的发明者,提出了 Paxos 算法。他虚拟了一个叫做 Paxos 的希腊城邦,这个岛按照议会民主制的政治模式制定法律,但是没有人愿意将自己的全部时间和精力放在这件事上。所以无论是议员、议长或者传递纸条的服务员都不能承诺别人需要时一定会出现,也无法承诺批准决议后者传递消息的时间

各角色定义

  • Proposer :提议者,提出议案(同时存在一个或者多个,他们各自发出提案);
  • Acceptor:接受者,收到议案后选择是否接受;
  • Client:产生议题者,发起新的请求;
  • Learner:最终决策学习者,只学习正确的决议

注意点
在这里的这个问题中,有几点是需要注意

  1. 在这个场景中,议员之间的通信时间不能保证。但通信总是能到达的,就是时间问题
  2. Learner可以先不管
  3. 算法的目的是保证多数派数据一致。少数派数据混乱,丢失可以是允许的。

2.2 算法内容

先把结论抛在这里,为什么要这么做。后面会讲到

我们先看看 Paxos 在原作者的《Paxos Made Simple》中的描述。
决议的提出与批准

通过一个决议分为两个阶段:

prepare 阶段

  1. proposer 选择一个提案编号 n 并将 prepare 请求发送给 acceptors 中的一个多数派;
  2. acceptor 收到 prepare 消息后,如果提案的编号大于它已经回复的所有 prepare 消息,则 acceptor 将自己上次接受的提案回复给 proposer,并承诺不再回复小于 n 的提案;
    下图是一个 proposer 和5个 acceptor 之间的交互,对2种不同的情况做了处理。
    在这里插入图片描述

批准阶段

  1. 当一个 proposer 收到了多数 acceptors 对 prepare 的回复后,就进入批准阶段。它要向回复 prepare 请求的 acceptors 发送 accept 请求,包括编号 n 和 value;
  2. 在不违背自己向其他 proposer 的承诺的前提下,acceptor 收到 accept 请求后即接受这个请求。
    在这里插入图片描述

2.3 第一版法律-议员必须接受

这个Paxos城邦有个平民(Client)向议长(Proposer )提出了一个自己的请求。议长看到了请求后,觉得合离,就决定颁发一项新的议案。但这项议案需要 多数派议员(acceptor) 同意才能生效。

但Paxos这个城邦也是刚成立的,对议案的流程也没有做出相关法律规定。所以有些议员拿到后,有人同意,有人失败。有人不理睬。
那么就会出现一种情况,议案同意数量和不同意的数量可能会五五开。那么久无法保证这项议案的一致性了。
所以出了第一版法律:议员接受到议长的议案后,只管同意

2.4 两个阶段+规则

就这样正常运转了一段时间后,问题又出现了。因为存在多个议长p1 和 p2。因为通信时长是不保障的,所以如果有3个议员C1,C2,C.当有3个议案时,存在可能:每个议员受到的顺序不一致

接收次序C1C2C3
1p1-ap2-ap1-b
2p2-ap1-ap2-a
2p1-bp1-bp1-a

那这时候,每个议员的议案数据又不一致了(一致性也包括了顺序).所以议案流程,还是得改。

现在的问题:

  1. 议员拿到议案,就在本地直接通过了。顺序很随机,跟收到议案的时间有关系。所以必须按某个规则,对收到议案进行判断。部分通过,部分不通过。

继续思考

  • 因为议员对议案不再是直接通过,所以议长提议案需要分成两个阶段。第一个阶段是问所有的议员是否同意,如果大多数同意。议长就再发一个批准命令。如果大多数不同意,则再发一遍议案(重新来过
  • 那这个规则是怎么样的。总不可能是随机的。议员可能会对两个议长的议案同时发回同意,那当接收到两个议长的批准命令后。必须要舍弃一个批准命令。并告诉议长结果。

2.5 算法为什么能保证一致性

2.2 里面我们已经看到了算法内容。完整的推导过程,上面,我只写了部分(实在写不出来了😔)

那我们先看看这个算法为什么可行。
关键是多数派(超过1/2)`以及各个议员的抛弃策略是一致的。

下面我举几个比较异常的场景,看这个算法是如何保证一致性的

  1. 两个议长(分别提出提案编号3和4的议案)几乎同时受到了超过半数的议员的同意回复。于是他们两发出批准命令。两个多数派里面必定有一个交集,那么这个交集a议员,如果先受到提案4批准命令.那么之后会拒绝提案3的批准命令。如果先受到提案3批准命令,根据算法也会拒绝。最后的结果肯定是大的(4)这个提案被通过。提出提案3的议长最终(时间不能确定)也会知道它的提案3没有被大多数议员通过。就会增加提案编号,再发一次。

问题

因为传输时间不一定。可能会出现提出提案3的议长受到了上面a议员的拒绝回复后,马上发5号提案。那么这时提案4也不能通过了。仔细想想,可能会出现两个(甚至多个)议长交替发出n号议案。然后没人能通过。这就是活锁现象

工业上的解决办法就是随机停止发送一段时间


其次每个议长的编号如何取值也是问题。

2.6 小结

Paxos虽然能解决一致性问题,但是还是很难实现的。所以后面又出现了基于paxos的其他更简单实现的一致性算法。

三 Raft

3.1 基于Raft的复制状态机系统架构

下图展示了执行一条客户端写命令的过程(z←6表示把6写入z):

  1. 客户端3发送一个状态机命令z< -6给服务器C的一致性算法模块。
  2. 一致性算法模块把状态机命令写入服务器C的日志,同时发送日志复制请求给服务器A和服务器的一致性算法模块。服务器A和服务器B的一致性算法模块在接收到日志复制请求之后,分别在各自的服务器上写入日志,然后回复服务器C的一致性算法模块。
  3. 服务器c的一致性算法模块在收到服务器A和B对日志复制请求的回复之后,让状态机执行来自客户端的命令。
    4.服务器c的状态机把命令执行结果返回给客户端3。

在这里插入图片描述

3.2 Raft日志复制

一个Raft集群包括若干服务器。服务器可以处于以下三种状态: leader、 follower 和candidate。只有leader处理来自客户端的请求。Follower不会 主动发起任何操作,只会被动的接收来自leader和candidate的请求。
在正常情况下,Raft集群中有一个leader, 其他的都是follower。Leader在接受到一个写命令之后,为这个命令生成一个日志条目,然后进行日志复制。

leader通过发送AppendEntries RPC把日志条目发送给follower,让follower把接收到的日志条目写入自己的日志文件。另外leader也会把日志条目写入自己的日志文件。日志复制保证Raft集群中所有的服务器的日志最终都处于同样的状态。
在这里插入图片描述

3.3 Raft选举算法

Raft使用心跳机制来触发leader选取。一个follower只要能收到来自leader或者candidate的有效RPC,就会一直处于follower状态。leader在每一 个election timeout向所有follower发送心跳消息来保持自己的leader状态。
如果follower在一个election timeout周期内没有收到心跳信息,就认为目前集群中没有leader。此follower
会对自己的currentTerm进行加一操作,并进入candidate状态,发起一轮投票。它会给自己投票并向其他所有的服务器发送RequestVote RPC一轮只有一次),然后会- -直处于candidate状态, 直到下列三种情形之一发生:

  1. 这个candidate赢得了选举。
  2. 另外一台服务器成为了leader。
  3. 一段时间之内没有服务器赢得选举。在这种情况下,candidate会再次发起选举。
    在这里插入图片描述

3.4 日志匹配

在这里插入图片描述

3.5 如何保证一个新term的leader保存了所有提交的日志条目

在这里插入图片描述

数学上证明就是:两个大多数(超过1/2),必然会有交集

3.6 状态机命令的提交点

这里没怎么看懂!
在这里插入图片描述

参考

  1. 《ZooKeeper实战与源码剖析》课程
  2. https://www.cnblogs.com/Soy-technology/p/11391851.html
  3. https://www.jianshu.com/p/2bceacd60b8a
  4. 分布式算法领域 Paxos 浅谈
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值