RAFT提供了一个颇具实践意义的分布式一致性协议的工程实现模板,具有很高的知名度。其大部分设计和viewstamp基本类似,而系统成员变更这一部分可以算作其真正的原创工作,但这一部分相比于论文其他部分,确实讲解最不详细的地方,最近在设计OCEANBASE的分布式系统,涉及到了成员变更的问题,仔细分析了RAFT的成员变更做法,和大家分享一下。
成员变更指的是系统成员变化,即server的上下线,这和由于宕机故障导致的上下线是不同的。宕机或者重启导致的上下线,是不会影响系统的注册的成员数量的,也就不会影响到一致性判断的所谓majority的生成,众所周知,majority是所有一致性的基础。成员变更时,会修改注册的成员数量,比如在实际应用中,为了提高安全等级,就很可能出现需要把备机数量由三台扩充到五台,在这种情况下,就发生了成员变更。
成员变更有多种实现方案,不论何种做法,都需要先将新成员网络接通,并把之前的日志数据同步给新成员,让其和现有leader日志保持同步。
完成这一基础步骤之后,就有多种选择了。比较丑陋的变更方案是,先停止写服务,然后写一条成员变更的同步给原有集群的majority,让原有集群下线,然后启动新集群,提供写服务。这种实现是简单,但可用性不高。
RAFT中给出的方案,提出了通过一个中间过渡阶段,joint consensus,逐步把数据写入的新的group中。
其具体做法是2阶段提交式的:
这个过程看起来比较复杂,其实从宏观来理解,可以把Cnew,看作原有集群的一个热备,在joint consensus阶段,一个请求要写入原有系统和热备,之后,不论<Cold, Cnew>这条日志是否写成功到多数派,不论热备出现了何种故障,原有系统会一直保证数据是一致的。
当写入<Cnew>到多数派备机成功后,就保证了新group和备有了一致且完备的数据,在这种情况下,新group就可以接替原有集群工作了。
再深入考虑下,<Cold, Cnew>和<Cnew>写失败的处理方式:
RAFT中成员变更过程以及失败回滚分析,布布扣,bubuko.com
原文:http://blog.csdn.net/zhang_shuai_2011/article/details/38585725