为了更好的做好容灾保障,使业务能够应对机房级别的故障,滴滴的存储服务都在多机房进行部署。本文简要分析了 Redis 实现异地多活的几种思路,以及滴滴 Redis 异地多活架构演进过程中遇到的主要问题和解决方法,抛砖引玉,给小伙伴们一些参考。
Redis 异地多活的主要思路
业界实现 Redis 异地多活通常三种思路:主从架构、Proxy双写架构、数据层双向同步架构。
主从架构
主从架构的思路:
主从架构的优点:
主从架构的缺点:
数据层双向同步架构的思路:
数据层双向同步架构的优点:
-
支持存量数据的同步
数据层双向同步架构的缺点:
滴滴 Redis 架构
Codis 架构(早期架构,现已废弃)
Kedis 架构(线上架构)
滴滴 Redis 异地多活架构的演进
第一代多活架构
第一代 Redis 多活基于 Codis 架构在 proxy 层实现了双写,即本机房的 Proxy 将写流量转发到对端机房的 Proxy,这个方案的特点是快速实现,尽快满足了业务多机房同步的需求。如前面 Proxy 双向架构思路所讲,本方案还存在着诸多缺点,最主要的是网络故障时,同步数据丢失的问题,为了解决这些问题,我们开发了第二代多活架构。
第二代多活架构
第二代多活基于 Kedis 架构,对 Redis-server 进行改造,可以把增量数据从 Redis 直接写入本机房的 MQ 中,由对端机房的 consumer 来消费 MQ,consumer 将数据写入对端 Redis 中。网络故障时,数据会在 MQ 堆积,待网络恢复后,consumer 可以基于故障前的 offset 继续进行消费,写入对端 Redis,从而保证在网络故障时 Redis 多活不会丢数据。
-
RedisServer 内部包含了 ProducerThread,当中间内部 queue 累积数据量超过10000条时,数据会被 MainThread 丢掉
-
Redis 增量数据写入 MQ,导致成本增加
第三代多活架构
在第三代架构中,我们细化了设计目标,主要思路是保证同步链路中的数据不丢不重,同时去掉对 MQ 的依赖,降低多活成本。
第三代架构中,我们去掉了 MQ 和 consumer,新增了 syncer 组件。syncer 组件模拟 Redis-slave 从 Redis-master 中拉取增量数据,这样把数据同步和 Redis 进行解耦,便于后续多机房扩展。
在第三代架构中,Redis 遇到了回环、重试、数据冲突、增量数据存储和读取等问题,接下来一一介绍我们应对这些问题的解决方案。
1、回环问题
机房-A 写入的数据同步到机房-B,防止数据再传回机房-A。
2、重试问题
机房-A 写入的 incrby 请求同步到机房-B,由于中间链路的重试,导致机房-B 可能执行了多次。
-
机房-A 的 Redis-master 向 syncer 同步了 incrby k 1 opinfo[opid=100] 请求, 之前同步的 opid=99 的请求已经成功
-
假设机房-A 的 syncer 将本条请求进行了重试,又执行了一遍 incrby k 1 opinfo[opid=100]
3、数据冲突问题
对于数据冲突,不同数据类型的不同操作的数据合并,如果单从存储层解决,是一个非常复杂的话题。如果业务层做了单元化部署,则不会出现这种问题。如果业务层没有做单元化,我们开发了冲突检测功能,来帮助业务及时发现数据冲突,最后数据以哪边为准来修正,需要业务同学来决策。
以上是冲突检测的基本原理,这是一个旁路统计,帮助用户发现一些潜在冲突数据。
4、增量数据存储和读取问题
因为 syncer 只是同步组件,不会存储数据,所以需要考虑当网络故障时,增量数据的存储和读取问题。
为了解决这个问题,我们对 Redis 的 aof 机制进行了改造,可以在网络故障时,增量数据都堆积在 Redis 的磁盘上,在网络恢复后,syncer 从 Redis 里拉取增量 aof 数据发送到对端机房,避免数据丢失。
aof 机制改造有:aof 文件切分、aof 增量复制、aof 异步写盘
开源 Redis 是在主线程中进行 aof 写盘,当磁盘 IO 过高时,Redis 写盘可能造成业务访问 Redis 耗时抖动。因此我们开发了 aof 异步写盘机制:
原文地址:https://blog.csdn.net/DiDi_Tech/article/details/134410944
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_40854.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!