应用级容灾
DR 是大型分布式系统不能绕开的问题。对于大型分布式交易系统,我们一般追求的 DR 目标是:
RTO(Recovery Time Objective)约等于 0:RTO 由于网络延迟的存在,如果要完全等于 0,等于交易的时候需要双写,对于性能的影响比较大。所以我们容忍网络延迟,RTO 的目标设定在约定于 0。
RPO(Recovery Time Objective)等于 0:RPO 不等于 0 意味着有数据丢失,这个对于关键的交易系统是基本不可忍受的。所以我们对于 RPO 的目标设定在严格等于 0。
为了实现上述的目标,需要实现在分布式系统中数据的同步复制能力。这里有两类的数据同步方式:基础设施实现的同步和应用实现的同步。
基础设施完成的数据同步这个大家接触的比较多,存储层实现 RAID 这个也可以算一种,但是我们平常用的比较多的是基于数据库的 binlog 同步。主库在事务中完成 binlog 的落地,从库同步 binlog 后回放操作完成数据的复制。
对于 NoSQL 的存储,比如消息队列,采用的是消息队列自身提供的 replication 能力,比如 kafka 的多副本,完成数据的多副本存储。
依赖基础设施的数据同步,可以完成大部分的容灾能力的建设。但是对于一些对于稳定性要求极高的系统,如果 binlog 同步出现延迟,或者 kafka 的底层副本能力由于网络问题造成 ISR 中已经没有可用 follower 的极端情况下,也会造成 RPO<>0,从而导致容灾的时候数据丢失。
在这种情况下,我们就需要考虑在应用层面实现数据的复制能力。基本的原理就是数据的异构备份——双写。平时大致用过的方式有如下几种:
binlog 异构同步。
基于事务型消息的备份。
基于 event 回放的同步。
binlog 异构同步和 mysql 的主从复制类似,也是采用 binlog 回放的方式进行数据副本,但是在 binlog 和备份集群之间,引入特殊的 ETL 能力:
可以基于 CANAL 完成 binlog 的实时采集;
完成 binlog 采集后,将同步指令通过消息的方式发往备份集群;
备份集群完成回放了数据的写入。
基于消息的备份首先需要引入能实现事务型消息的基础设施。保证数据库事物和消息发送的原子性。这里有三种方式:
引入支持 XA 协议的消息中间件。这种方式比较重,一般不用。
在事务中进行消息发送,同时消息处理的时候通过回查逻辑判断是否事务未提交成功需要忽略消息。
先落库在异步发送消息。
我们一般采用第二种方式。
有了事务型消息的基础设施后,我们可以在提交数据库事务的同时,发送数据变更消息。备份集群处理数据同步消息,完成数据的复制能力。
基于 event 的同步需要基于 event driven 进行架构设计。基于 event driven 架构,将主备集群之间数据复制转化为 event 的双写。通过实现 event 在主备集群之间的双写能力,再加上 event 回放的方式,完成主备集群之间的数据复制。
event 的双写,可以采用 binlog 异构同步或者基于事务型消息同步方式。
应用级别同步,除了可以对基础设施的数据同步能力进行补充形成双重保护之外,还可以支撑跨洲等网络延迟过大(200ms 以上)而不能适用基础设施同步能力的场景。我们在进行跨洲容灾的场景下,一般都会采用应用级别的数据同步方式。
版权声明: 本文为 InfoQ 作者【agnostic】的原创文章。
原文链接:【http://xie.infoq.cn/article/3df4e301755a9b625c030ba7f】。文章转载请联系作者。
评论