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

  • 如果能够通过复制缓冲区同步 , 主节点给从节点返回 +CONTINUE runId
  • 如果不能够通过复制缓冲区同步 , 主节点给从节点返回 +LPSYNC
  • 如果从节点收到+CONTINUE , 则继续接收增量数据即可 , 并继续更新offset和命令id
  • 如果从节点收到+LPSYNC , 则从节点继续给主节点发送 LPSYNC runId id
  • 主节点收到LPSYNC命令后 , 如果能够通过rlog继续同步数据 , 则给从节点发送 +LCONTINUE runId;
  • 从节点收到+LCONTINUE后 , 可以把offset设置为LONG_LONG_MIN , 或者后续数据不更新offset;继续接收通过rlog同步的增量数据即可;
  • 通过rlog同步的增量数据传输完毕后 , 主节点会给从节点发送 lcommit offset命令;
  • 从节点在解析数据的过程中 , 收到lcommit命令时 , 更新本地offset , 后续的增量数据继续增加offset , 同时lcommit命令无需同步到对端(通过id<0识别即可 , 所有id<0的命令均无需同步到对端)
  • 如果不能 , 此时主节点给从节点返回 +FULLRESYNC runId offset;后续进行全量同步;
  • 2、幂等性【京东科技Redis跨数据中心双向同步优化实践】迁移工具为了提高性能 , 并不是实时往zk保存同步偏移offset和id , 而是定期(默认每秒)向zk进行同步 , 所以当断点续传时 , 迁移工具从zk获取断线前同步的偏移 , 尝试向主节点继续同步数据 , 这中间可能会有部分数据重复发送 , 所以为了保证数据一致性 , 需要保证命令多次执行具备幂等性 。
    为了保证redis命令具备幂等性 , 对redis中部分非幂等性命令进行了改造 , 具体设计改造的命令如下所示:
    京东科技Redis跨数据中心双向同步优化实践

    文章插图
     
    注:list类型命令暂未改造 , 不具备幂等性
    3、数据回环处理数据回环主要是指 , 当同步工具从A机房redis读取的数据 , 通过MQ同步到B机房写入后 , B机房的同步工具又获取到 , 再次同步到A机房 , 导致数据循环复制问题 。
    对于同步到从节点以及迁移工具的数据 , 会在头部添加id字段 , 针对不同来源的数据或者无需同步到远端的数据通过id来标识区分;本地业务客户端写入的数据需要同步到远端数据中心 , 分配id大于0;来源于其他数据中心的数据分配id小于0;一些仅用于主从心跳交互的命令数据分配id也小于0 。
    同步工具解析完数据后 , 过滤掉id小于0的命令 , 只需要向远端写入id大于0的数据 , 即本地业务客户端写入的数据 。来源于其他数据中心的数据均不回写到远端数据中心 。
    4、过期与淘汰数据目前过期与淘汰均由各数据中心redis节点分别独立处理 , 由过期与淘汰删除的数据不进行同步;即由过期与淘汰产生的删除命令其id分配为小于0 , 并由同步工具过滤掉 。
    (1)同步产生的问题为什么不同步过去?因为在内存中hash表里面保存的数据没有标记数据中心来源 , 过期与淘汰的数据有可能来自于其他数据中心 , 如果来自于其他数据中心的数据被过期或淘汰并且又同步到远端其他数据中心 , 就会出现数据双写冲突的场景 。双写冲突可能会导致数据不一致 。
    (2)不同步产生的问题对于过期数据来说 , 不同步删除可能会导致不同数据中心数据显示不一致 , 但是一定会最终一致 , 且不会出现脏读;
    对于淘汰数据来说 , 目前的不同步删除的方案 , 假如出现淘汰 , 会导致不同数据中心数据不一致;目前只有通过运维手段 , 比如充足预分配、及时关注内存使用率告警 , 来规避淘汰数据现象发生 。
    5、数据迁移在redis集群模式中 , 一般是在发生横向扩容增加集群主节点数时 , 需要进行槽以及数据的迁移 。
    redis集群中数据迁移以槽为维度进行迁移 , 将槽中所有数据从源节点迁移到目标节点 , 然后将槽号标记为由新的目标节点负责 , 同时每迁移完一个Key , 会在源节点中进行删除 , 将migrate命令替换为del命令;同时迁移数据是在源节点中给目标节点发送restore命令实现 。


    推荐阅读