在正常同步后第一次收到错误的SyncSeq,回应主节点自己所期望的SyncSeq,主节点收到回应后,会从备节点所期望的SyncSeq开始同步,需要注意的是,备节点在连续收到错误SyncSeq时,只需对第一个错误回应,否则主节点会出现重复同步的情况;
同步连接在断连后重新连接时,备节点告知主节点自己所期望开始同步的SyncSeq,主节点从该SyncSeq开始同步;
SyncSeq符合期望但执行出错,一般是增量同步才可能出现,备节点回应主节点同步出错,主节点收到回应后,把出错的同步包改为全量同步。
在增量同步和全量同步交叉进行的情况下,如果某次全量同步已同步了最新的数据,后续的增量同步可能导致写操作重复执行,为了避免这种情况,备节点会校验同步包中的SyncSeq和数据中的SyncSeq,如果前者不大于后者,说明数据已执行了这次写操作,直接跳过不执行,也不需要回应主节点,这就是为什么需要在数据中保存SyncSeq的原因。
通过上面介绍和分析,可以看出采用同步连接、批量同步的方法,正常情况下只有单向的同步流量,是非常高效的;而在异常情况下,通过出错回应、SyncSeq校验等机制,保证了同步的可靠性。
容灾机制如果系统需要具有容灾能力,即在机器发生故障时,系统的可用性基本不受影响,那么系统中所有数据至少需要有两个以上的副本,并且系统的处理能力要有一定的冗余,需要保证在故障机器不能提供服务时,系统不会过载。一般来说,数据的副本数量越多,系统的处理能力越冗余,系统的容灾能力越强。更进一步,还需要考虑物理部署,通过把数据的不同副本分布在不同机架、不同机房、甚至是不同城市,来把系统的容灾能力提升到不同的级别。
配置运维中心会监控系统存储层所有节点的状态,存储节点会定时上报心跳,如果配置运维中心在一段时间未收到某个存储节点的心跳,则把该节点的状态标记为故障,并进行故障处理流程。首先需要禁止故障节点继续提供服务,即通知接口层不再把客户端请求转发的故障节点,如果故障节点是主节点,配置运维中心会查询并对比所有备节点的同步进度,选择数据最新的备节点,将其切换为主节点。由于所有备节点也会记录Binlog,所以在切换为主节点之后,可以直接向其它备节点进行同步。这里的主备切换可能会导致少量的数据丢失,如果业务不能容忍这样的数据丢失,则需要使用其它强一致性的方案。
在容灾切换之后,还需要进行故障节点的恢复,以便系统恢复到正常的状态。故障机器恢复后,就会进入死机恢复流程,无论故障节点在故障前是主节点还是备节点,故障恢复后的角色都是备节点。首先待恢复节点需要把机器上所有的数据清空;接着主节点会把当前所有VNode的SyncSeq复制到待恢复节点,并且全量复制所有数据;在全量复制完成之后,开始进行数据同步,由前面的同步机制可知,同步的SyncSeq会从之前复制到待恢复节点的状态开始追赶;在主节点和待恢复节点之间的SyncSeq差异缩小到正常范围时,待恢复节点的角色就变为备节点,开始提供服务。
配置运维中心会监控主备节点之间的SyncSeq差异,如果某个备节点差异达到一定的阈值,则禁止该备节点提供服务,如果差异在比较长的时间之后仍然无法恢复,则会触发死机恢复流程。
数据回档最后再简单介绍下数据冷备和回档,主要是由备份系统负责。备份任务一般是手动或定时发起,属于业务级别的,备份系统收到一个业务的备份任务后,会远程备份业务的所有数据,过程比较简单,就是遍历所有的存储节点,把属于该业务的所有数据写入到远程文件系统中,每次备份都需要记录开始时间和结束时间,作为数据回档的基准。
系统中所有的写操作都会记录一份远程的流水,每条流水都记录了写操作的时间戳,由流水中心统一存储。结合数据冷备和流水,可以恢复到冷备完成后任意时刻的数据。备份系统收到一个业务回档任务后,首先停止该业务的服务,然后清空业务的所有数据,接着从冷备做一次全量的恢复,然后再重放流水到指定时间点,即可完成数据回档。需要注意的是这里的冷备并不是快照,在进行冷备的时候,写操作也正常执行,所以从冷备开始时间重放流水会导致很多的写操作重复执行,这里通过数据版本校验来避免这个问题,在数据中保存了版本信息,在写操作流水中也记录了对应的写操作完成后的数据版本,重放流水的时候,如果流水中记录的版本不比数据中的版本新,则直接跳过这条流水,这样就保证了数据回档的准确性。