原生Redis跨数据中心双向同步优化实践( 三 )


3、日志文件删除为了防止日志文件数量无限增长并且消耗磁盘存储空间 , 以及由于未做日志重写、通过过多的文件进行断点续传效率低下、意义不大 , 所以redis定期对日志文件和相应的索引文件进行删除 。
默认日志文件最多保留一天 , redis定期删除一天以前的日志文件和索引文件 , 也就是最多容忍一天时间的机房级故障 , 否则需要进行机房间数据全量同步 。
在断点续传时 , 如果需要从日志文件中同步数据 , 在同步开始前会临时禁止日志文件删除逻辑 , 待同步完成后恢复正常 , 避免出现在同步的数据被删除的情况 。
五、redis数据同步1、断点续传如前所述 , 为了容忍更长时间的机房级故障 , 提高跨数据中心容灾能力 , 提升机房间故障恢复效率 , 我们对redis同步流程进行改造 , 当部分同步中无法使用环形复制缓冲区完成同步时 , 增加先尝试使用日志rlog进行同步 , 流程图如下所示:

原生Redis跨数据中心双向同步优化实践

文章插图
首先 , 同步工具连接上主节点后 , 除了发送认证外 , 需要先通过replconf capa命令告知主节点具备通过rlog断点续传的能力 。
  1. 从节点先发送psync runId offset , 如果是第一次启动 , 则先发送psync ? -1 , 主节点会返回一个runId和offset
  2. 如果能够通过复制缓冲区同步 , 主节点给从节点返回 +CONTINUE runId
  3. 如果不能够通过复制缓冲区同步 , 主节点给从节点返回 +LPSYNC
  4. 如果从节点收到+CONTINUE , 则继续接收增量数据即可 , 并继续更新offset和命令id
  5. 如果从节点收到+LPSYNC , 则从节点继续给主节点发送 LPSYNC runId id
  6. 主节点收到LPSYNC命令后 , 如果能够通过rlog继续同步数据 , 则给从节点发送 +LCONTINUE runId;
  7. 从节点收到+LCONTINUE后 , 可以把offset设置为LONG_LONG_MIN , 或者后续数据不更新offset;继续接收通过rlog同步的增量数据即可;
  8. 通过rlog同步的增量数据传输完毕后 , 主节点会给从节点发送 lcommit offset命令;
  9. 从节点在解析数据的过程中 , 收到lcommit命令时 , 更新本地offset , 后续的增量数据继续增加offset , 同时lcommit命令无需同步到对端(通过id<0识别即可 , 所有id<0的命令均无需同步到对端)
  10. 如果不能 , 此时主节点给从节点返回 +FULLRESYNC runId offset;后续进行全量同步;
2、幂等性迁移工具为了提高性能 , 并不是实时往zk保存同步偏移offset和id , 而是定期(默认每秒)向zk进行同步 , 所以当断点续传时 , 迁移工具从zk获取断线前同步的偏移 , 尝试向主节点继续同步数据 , 这中间可能会有部分数据重复发送 , 所以为了保证数据一致性 , 需要保证命令多次执行具备幂等性 。
为了保证redis命令具备幂等性 , 对redis中部分非幂等性命令进行了改造 , 具体设计改造的命令如下所示:
原生Redis跨数据中心双向同步优化实践

文章插图
注:list类型命令暂未改造 , 不具备幂等性
3、数据回环处理数据回环主要是指 , 当同步工具从A机房redis读取的数据 , 通过MQ同步到B机房写入后 , B机房的同步工具又获取到 , 再次同步到A机房 , 导致数据循环复制问题 。

经验总结扩展阅读