关于raft解决分布式一致性中的幽灵复现方案

分布式中 幽灵复现是指在不同的时间点读取同一份数据可能出现前后不一致的问题,其本质还是分布式一致性没有得到保障

现象

有三台节点 a b c,初始日志复制如下[数值表示term 数值下标表示index]
a 1 1
b 1 1
c 1 1

假设 a写入日志
a 1 1 1                             【1】  【1】 【1】三条term为1 ,index为0,1,2
                                     假设日志内容是 add [x=1] [y=2] [z=3]
b 1 1
c 1 1
此时a挂掉,b成为leader
b 1 1
c 1 1
此时读取数据为x=1 y=2  z 的日志由于a挂掉读取不到


假设此时b挂掉 a再次选举 a的index和term决定a可以成为leader
此时读取数据为x=1 y=2  z=3

出现幽灵复现 即在第二轮没有读到的数据在第三轮读到

raft解决方案

不同的一致性算法有不同的解决方案
raft如下解决

1 每次选举term++,随后追加当前term的NOOP日志
2 commitIndex 只有term相同的时候才可以提交
3 日志服从leader节点可以回退


假设初始a,b,c如下,【假设a是leader】
a  1 2 
b  1 2 
c  1 2 
A 以下情形 【不可以存在,index=2 ,term=3 的日志如果没有过半 a无法提交commitindex 就不会出现
index=3,term=3的日志】

a 1 2 3 3
b 1 2
c 1 2

B1
a 1 2 (3) (3)
b 1 2  3
c 1 2        




B2 a挂掉b  此时只能是b选择leader 日志一致
a 1 2 
b 1 2  3
c 1 2


B11
a 1 2 (2) (2)
b 1 2  2
c 1 2


B2 a挂掉 c选择leader 追加noop,b的index=2 term 不同于leader 开始backoff 最终日志一致
假设没有term约束 那么b,c在index = 2 的term则会不一致
a 1 2 
b 1 2    2
c 1 2  【3】noop





案例多多,最终相关结论如下

新leader必须追加noop日志解决幽灵复现,同时新leader认为所有follower的节点nextindex和noop之前相同,但还没有感知到matchindex matchindex全部为0

追加日志必须 previndex >= last prevterm 和lastterm相同 

commitindex leader 必须term相同 newcommitindex> commitindex

如果日志匹配不上follower需要回退,leader会回退nextindex重新发起日志直到匹配成功后确定backoffsetindex

append必须比较term和previndex 【这点可以类比区块链】

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值