京东科技Redis跨数据中心双向同步优化实践( 二 )


3、同步流程改造原生redis数据同步分为全量同步和部分同步 , 并且每个主节点有一个内存环形复制缓冲区;初次同步使用全量同步 , 断点续传时使用部分同步 , 即先尝试从主节点环形复制缓冲区中进行同步 , 同步成功的话则同步完缓冲区中的数据后即可进行增量数据同步 , 如果不成功 , 则仍然需要先进行全量同步再增量同步 。
由于全量同步需要生成一个子进程 , 并且在子进程中生成一个RDB文件 , 所以对主节点性能影响比较大 , 我们应该尽量减少全量同步的次数 。
为了减少全量同步的次数 , 我们对redis同步流程进行改造 , 当部分同步中无法使用环形复制缓冲区完成同步时 , 增加先尝试使用日志rlog进行同步 , 如果同步成功 , 则同步完日志中数据后即可进行增量同步 , 否则需要先进行全量同步 。
 
四、rLog日志设计分为索引文件与日志文件 , 均采用顺序写的方式 , 提高性能 , 经测试与原生redis开启aof持久化性能一致;但是rlog会定期删除 , 原生redis为了防止aof文件无限膨胀 , 会定期通过子进程执行aof文件重写 , 这个对主节点性能比较大 , 所以实质上rlog对redis的性能相对于aof会更小 。
索引文件和日志文件文件名均为文件中保存的第一条命令的id 。
索引文件与日志文件均先写内存缓冲区 , 然后批量写入操作系统缓冲区 , 并每秒定期刷新操作系统缓冲区真正落入磁盘文件中 。相比较于aof文件缓冲区 , 我们对rlog缓冲区进行了预分配优化 , 达到提升性能目的 。
1、索引文件格式索引文件格式如下所示 , 每条命令对应的索引数据包含三部分:

京东科技Redis跨数据中心双向同步优化实践

文章插图
 
  • pos:该条命令第一个字节在对应的日志文件中相对于该日志文件起始位置的偏移
  • len:该条命令的长度
  • offset:该条命令第一个字节在主节点复制缓冲区中累积的偏移
 
2、日志文件拆分为了防止单个文件无限膨胀 , redis在写文件时会定期对文件进行拆分 , 拆分依据两个维度 , 分别是文件大小和时间 。
默认拆分阈值分别为 , 当日志文件大小达到128M或者每隔一小时同时并且日志条目数大于10w时 , 写新的日志文件和索引文件 。
在每次循环处理中 , 当内存缓冲区的数据全部写入文件时 , 判断是否满足日志文件拆分条件 , 如果满足 , 加上一个日志文件拆分标志 , 下一次循环处理中 , 将内存缓冲区数据写入文件之前 , 先关闭当前的索引文件和日志 , 同时新建索引文件和日志文件 。
3、日志文件删除为了防止日志文件数量无限增长并且消耗磁盘存储空间 , 以及由于未做日志重写、通过过多的文件进行断点续传效率低下、意义不大 , 所以redis定期对日志文件和相应的索引文件进行删除 。
默认日志文件最多保留一天 , redis定期删除一天以前的日志文件和索引文件 , 也就是最多容忍一天时间的机房级故障 , 否则需要进行机房间数据全量同步 。
在断点续传时 , 如果需要从日志文件中同步数据 , 在同步开始前会临时禁止日志文件删除逻辑 , 待同步完成后恢复正常 , 避免出现在同步的数据被删除的情况 。
 
五、redis数据同步1、断点续传如前所述 , 为了容忍更长时间的机房级故障 , 提高跨数据中心容灾能力 , 提升机房间故障恢复效率 , 我们对redis同步流程进行改造 , 当部分同步中无法使用环形复制缓冲区完成同步时 , 增加先尝试使用日志rlog进行同步 , 流程图如下所示:
京东科技Redis跨数据中心双向同步优化实践

文章插图
 
首先 , 同步工具连接上主节点后 , 除了发送认证外 , 需要先通过replconf capa命令告知主节点具备通过rlog断点续传的能力 。
  1. 从节点先发送psync runId offset , 如果是第一次启动 , 则先发送psync ? -1 , 主节点会返回一个runId和offset


    推荐阅读