RAFT中成员变更过程以及失败回滚分析

RAFT提供了一个颇具实践意义的分布式一致性协议的工程实现模板,具有很高的知名度。其大部分设计和viewstamp基本类似,而系统成员变更这一部分可以算作其真正的原创工作,但这一部分相比于论文其他部分,确实讲解最不详细的地方,最近在设计OCEANBASE的分布式系统,涉及到了成员变更的问题,仔细分析了RAFT的成员变更做法,和大家分享一下。

成员变更指的是系统成员变化,即server的上下线,这和由于宕机故障导致的上下线是不同的。宕机或者重启导致的上下线,是不会影响系统的注册的成员数量的,也就不会影响到一致性判断的所谓majority的生成,众所周知,majority是所有一致性的基础。成员变更时,会修改注册的成员数量,比如在实际应用中,为了提高安全等级,就很可能出现需要把备机数量由三台扩充到五台,在这种情况下,就发生了成员变更。

成员变更有多种实现方案,不论何种做法,都需要先将新成员网络接通,并把之前的日志数据同步给新成员,让其和现有leader日志保持同步。

完成这一基础步骤之后,就有多种选择了。比较丑陋的变更方案是,先停止写服务,然后写一条成员变更的同步给原有集群的majority,让原有集群下线,然后启动新集群,提供写服务。这种实现是简单,但可用性不高。

RAFT中给出的方案,提出了通过一个中间过渡阶段,joint consensus,逐步把数据写入的新的group中。

其具体做法是2阶段提交式的:

  1. 先写一条<Cold, Cnew>同步到新旧两个group的多数派,写入这条日志后,系统中的任何写入请求,都要同步到Cold和Cnew 两个group的多数派才算写入成功

当<Cold, Cnew>同步成功后,再写一条<Cnew>,同步给新group,然后就可以完成切换了。

这个过程看起来比较复杂,其实从宏观来理解,可以把Cnew,看作原有集群的一个热备,在joint consensus阶段,一个请求要写入原有系统和热备,之后,不论<Cold, Cnew>这条日志是否写成功到多数派,不论热备出现了何种故障,原有系统会一直保证数据是一致的。

当写入<Cnew>到多数派备机成功后,就保证了新group和备有了一致且完备的数据,在这种情况下,新group就可以接替原有集群工作了。

再深入考虑下,<Cold, Cnew>和<Cnew>写失败的处理方式:

  1. 假设<Cold, Cnew>写失败,需要再写入<Cold>,回滚那些写入成功的少数派。如果在这之前,发生了重新选主,新主不论如果已经收到了<Cold, Cnew>,则其会将这条日志同步给备机,并将成员变更继续完成;如果新主没有收到<Cold, Cnew>,则这条日志会被覆盖,因此不会有任何问题。
  2. 如果<Cold, Cnew>已经写成功,而<Cnew>写失败,需要再写一条<Cold>将之前操作回滚。如果在回滚成功前,发生了重新选主,新主如果没有<Cnew>,则会覆盖<CneW>日志,继续处于joint consensus状态,如果有<Cnew>,则会将日志同步给新集群,然后进入一个新集群状态。                                                                                       此外,还有可能新集群中和老集群中都出现一个leader的情况,但此时,老集群中的leader由于还处于joint
    consensus状态,即必须把日志同步给新集群中的多数派才会成功,而此时若新集群已经有主,是不会应答老集群的日志同步请求的。

RAFT中成员变更过程以及失败回滚分析

时间: 2024-10-28 20:24:51

RAFT中成员变更过程以及失败回滚分析的相关文章

Transactional 事务回滚 分析

Spring的AOP事务管理默认是针对unchecked exception回滚(运行期异常,Runtime Exception). unchecked ,就是不用手工写try catch的exception Exception作为基类,下面还分checked exception和unchecked exception.如果客户端可以通过其他的方法恢复异常,那么这种异常就是checked exception:如果客户端对出现的这种异常无能为力,那么这种异常就是Unchecked exceptio

chunk writer 中需要对抛错的交易进行回滚,同时又要在其他表中记录是哪一笔交易记录失败

首先根据我有限的知识判断,回滚之后进行写表,该写表动作只能使用listener来进行. 考虑使用的listener有:ItemWriteListener     StepExecutionListener    ChunkListener 我首先使用了ItemWriteListener,在 onWriteError(Exception exception, List items) 方法中对items进行了写表,后来发现被回滚,通过一步一步debug,看到确实该方法之后才是rollback. 所以

乱序日志同步成员变更方案

尝试着论证下使用阻塞日志场景下,成员变更的正确性(支持变更少数派个成员,不能同时进行上线和下线两个操作): 1)备机slave收到[Cold,Cnew]的确认条件是要求之前的日志都已经收到,这样保证如果[Cold, Cnew]日志得到Cold, Cnew两个集群的多数派应答,那么[Cold, Cnew]之前的日志都已经在Cnew上形成了多数派: 2)[Cold, Cnew]和[Cnew]两条日志都是阻塞日志,即集群工作状态所有的成员变更日志都是阻塞日志.这里阻塞日志的概念和日照邮件中指出的是一致

Service中事务不能回滚的解决方式(转)

1.在service方法里面如果对异常进行了捕获的话,该事务是不会进行回滚的        默认spring事务只在发生未被捕获的 runtimeexcetpion时才回滚.          spring aop  异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样aop代理才能捕获到方法的异常,才能进行回滚,默认情况下aop只捕获runtimeexception的异常,但可以通过配置来捕获特定的异常并回滚,换句话说在service的方法中不使用try catch 或者在catc

关于调用方有事务,被调用的SP中也有事务,在嵌套SP中回滚代码的报错处理,好文推荐

SQL报错异常:Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0. --首先明确一点,在SQL中开启事务时,Begin Tran时,@@TRANCOUNT会加1,Commit Tran时@@TRANCOUNT会减1,但是当ROLLBACK TRAN时会把@@TranCount直接设置

oracle回滚机制深入研究

这篇文章主要描述oracle的回滚机制,篇幅可能较长,因为对于oracle的回滚机制来说,要讨论和描述的实在太多,只能刷选自己认为最有意义的一部分进行深入研究和分享 一.我们来看一个DML语句的处理过程描述 update undotest set object_type='VIEW' where object_type='PROCEDURE'; 检查shared pool中是否存在相同的语句,如果存在,重用执行计划,执行扫描运算,如果不存在,执行硬解析生成执行计划 根据执行计划中的扫描运算,检查

oracle_回滚

为了保证数据库中多个用户间的读一致性和能够回退事务.一.在一个简单的更新语句中,对于回滚段的操作存在多处,在事务开始时,首先需要在回滚表空间获得一个事务槽,分配空间,然后创建前镜像,此后事务的修改才能进行,oracle必须以此来保证事务是可以回滚的.如果用户提交了事务,oracle会在日志文件记录提交,并且写出日志,同时会在回滚段中把事务标记为已提交:如果用户回滚事务,则oracle需要从回滚段中把前镜像数据读取出来修改数据缓冲区,完成回滚,这个过程本身也要产生redo,所以回退这个操作是很昂贵

数据库事务处理机制之事务回滚问题讨论

一.Sql中的事务 概念:事物是一种机制,是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行.事务是一个不可分割的工作逻辑单元.在数据库系统上执行并发操作时事务是作为最小的控制单元来使用的.多用户登录系统适于使用事务机制. 属性:4大属性: a.原子性:事务时一个完整的操作.b.一致性:当事务完成时,数据库必须处于一致状态.c.隔离性:对数据进行修改的所有并发事务时彼此隔离的.d.持久性:事务完成后,它对于系统的影响是永久性的. 创建 (1)开始事务:begin t

重建回滚表空间

作者:iamlaosong 因为意外原因(掉电,人为杀死进程)导致回滚段中的数据没有提交,回滚段中保留大量数据无法去除,我想到的办法就是重建表空间.当Oracle中当读写大批量数据时候,如果不及时提交任务,会导致回滚表空间的迅速增加,回滚表空间会一直增大,而不自动释放它占用的硬盘空间,(当然,几个小时后,系统会自动释放它自身的占用率,但不会释放它所占用的硬盘空间),这时,也可以通过重建表空间来解决. 1.重建回滚表空间方法, 思路:先新建回滚表空间,再重新定向到新建的回滚表空间,然后删除掉原来的