目前redis仅支持主从复制模式,能够支持在线备份、读写分离等功能,实际应用中一般经过sentinel服务作主从切换的管理,这增长了管理的复杂度和维护成本,基于此360基础架构组联合DBA从redis内部实现了双主功能。 redis
redis支持树形的主从异步复制,并具备非阻塞、部分同步等特性,下面简单介绍下其实现原理以及目前redis主从复制模式在故障发生时的数据丢失状况。 缓存
slave开始链接到master时须要同步master已有的数据,具体过程以下图所示,主要有如下几个步骤: 网络
master 实例会维护其slave实例列表,当有更改操做发生时,其会经过链接创建时建立的socket向全部slave实例发送操做命令进行数据传播,同时为了防 止故障恢复slave从新链接master时每次都进行全量同步,master实例会内部维护一个缓冲区(积压空间)来缓存部分slave命 令,master数据传播的具体过程为: 架构
redis 主从模式并不能保证数据的100%完整,在网络故障、主库宕机等状况下提高slave为master时可能会丢失部分数据,以下图所示,假如在某个时刻 master的数据还未彻底传播给slave时,master宕机等状况发生并将slave提高为master,这时原来master未传播的一部分数据 将丢失。 异步
因为时间、精力等因素,目前咱们在进行双主设计时结合以下实际项目需求进行了一些设计折衷,后续咱们会继续完善相关设计。 socket
上层保证某个时间点只有一个master在写 性能
故障时容许丢失少许数据 spa
为 避免额外维护成本,双主模块彻底在redis内部实现,双主两个实例各自建立一个socket进行彼此通讯;加入双主复制后不会影响原有的主从复制模式, 但以下图所示,主从复制实例能够经过咱们新增的doublemasterof命令转化为双主复制,双主复制实例也能够经过原有的slaveof命令转换为 主从复制实例。 设计
redis 双主实例网络故障恢复或重启等状况下会进行从新链接以同步彼此数据,主从模式下同步策略很简单,只须要从库同步主库数据便可,而双主模式下咱们必须根据一 定的策略来选出一个实例做为数据同步的对象,咱们考虑到两种具体同步策略:基于数据量和基于时间戳的同步策略。 对象
基 于数据量的同步策略能够理解为数据量少的实例去同步数据量多的实例,这种同步策略在故障发生时数据已经所有传播到另一个实例的状况下,故障恢复后能够保 证数据完整性,但以下图所示,假如原来操做在双主A上执行,某一时刻双主A上的操做还未同步到双主B上发生了网络故障,上层会切到B上继续写入,当写入了 图中红色所示大小的数据后网络故障恢复,这时进行数据同步时就有可能丢失A或B上的部分数据。
对 于基于时间戳的同步策略,咱们会在redis内部维护双主实例的最近更新时间戳,故障恢复进行数据同步时时间戳较旧的实例会同步时间戳较新的实例;和基于 数据量同步策略同样当故障发生时若是数据已经所有传播到另外实例则故障恢复后能够保证数据完整性,不然,以下图所示故障恢复后将丢失双主A实例的部分数 据。
根据业务需求,咱们须要保证最新写入的数据不会丢失,因此具体实现上咱们选择了基于时间戳的同步策略。
咱们在redis原有的全同步,部分同步的基础上增长了ignore resync策略以实现双主同步,具体实现以下图所示,有如下几个步骤:
对 一个双主实例的更改操做,redis内部会经过双主实例创建链接时建立的socket异步传播给另外一个双主实例,这里要解决的问题是要避免数据再次传播回 来,具体实现上咱们经过双主实例的runid进行判断,每一个双主实例内部会维护其另一个实例的runid信息,当有更改命令要执行时,咱们会经过 runid来判断该命令是不是其双主实例传播过来的,若是是将再也不回传。
redis主从实现机制上,当通讯模块接收到主库的更改命令时会直接在从库上增长其复制偏移量来记录数据同步的位置,而对于双主实例咱们知道为避免数据循环传播,双主实例A传播给双主实例B的命令不会回传过来,那么该如何维护其复制偏移量呢?设计上咱们考虑了两种策略:
以下图所示,双主A向双主B传播一条数据后,B会回复A一个ACK length确认,A接收到确认信息后将本身的复制偏移量增长length。
以下图所示,双主A再向B传播数据以前本身主动增长复制偏移量,双主B不会向双主A回复确认信息
策略一对比策略二进一步保证了数据的完整性,但同时带来了必定的网络开销,两种策略都不能彻底保证复制偏移量再网路故障下的正确性(策略一在ACK丢失的状况下没法保证复制偏移量正确),结合目前的需求为了避免影响性能咱们选择了策略二。
结合目前项目的需求咱们在redis内部实现了双主功能,可是也有一些须要改进的地方,欢迎你们提出意见,后面咱们会不断完善,敬请关注!
http://weibo.com/p/1001603872517453663800