禧云Redis跨机房双向同步实践
编者荐语:
2019年4月16日跨机房Redis同步中间件(Rotter)上线,团餐率先商用:
以下文章来源于云纵达摩院 ,作者杨海波
禧云信息/研发中心/杨海波 20191115
关键词:Rotter,Redis,多活,跨机房,同步
一、项目介绍
1.1 系统架构
- 控制台Manager
- 节点发现和数据传输层(ZK+Redis)
- 数据同步层Rotter

- Manager负责任务配置、数据展示、监控报警等,各机房独立部署;
- ZK为跨机房集群,A机房为Leader节点,B机房为Follow节点。ZK在方案中负责Rotter节点的注册发现和任务调度。
- 多活Redis在方案中扮演数据队列的角色,降低了Manager和Rotter节点之间的耦合度。
- Rotter是Redis同步任务的执行者,包含replicator和sync两个角色。
- replicator是国人开源的基于java语言的redis主从协议实现者redis-replicator,负责解析redis节点指令。
- sync负责redis指令跨机房写入,处理同步回环,同步指令监控等。
1.2 同步流程

- ParseEventFilter:格式化同步指令;生成指令回环校验key;赋值指令所属DB;过滤Rotter自身产生的指令
- DBFilter:过滤掉不需要同步的DB
- KeyFilter:过滤掉不需要同步的KEY
- CircleSyncFilter:过滤掉回环指令和删除保护指令
- MultiThreadFilter:多线程分发,提高同步效率
- OvertimeFilter:经过队列积压,判断该指令是否已经过期
- DeleteKeyFilter:生成删除保护KEY
- RateLimitFilter:限流,包括带宽和指令数
- SendTargetFilter:执行目标redis写入
- MonitorFilter:监控和上报正在同步的指令
- ComputeRateFilter:计算同步速率、带宽、队列积压长度等
二、背景&目标
2.1 背景
2.2 目标
- 零侵入:业务系统不需要做任何改造就能接入
- 高吞吐量:基于现有业务峰值TPS乘以10,得出TPS要达到1万
- 低延时:我司的多活业务不会出现跨机房读取数据的情况,所以定的目标延时低于1s。实际情况延时在50ms左右
- 高堆积能力:基于跨机房网络的不确定性,当网络闪断时能够保证指令不丢失
- 高可用性:当网络故障或者Redis宕机恢复时,同步任务能自动恢复
- 可配置性:业务系统可以自由定制需要同步哪些Key
三、技术选型
- 我们需要提供一套统一的工具包,为每个指令提供一个是否需要同步到另一机房的参数;
- 我们可能还需要为工具包提供同步写另一机房还是异步写另一机房的参数;
- 写另一机房失败本机房数据是否需要回滚?
- 现在java业务系统使用jedis和redisson都有,适配难度大,且不利于客户端版本升级
- 代理的性能怎么样,代理本身的延时高不高?
- 我司现有Redis架构基本都是Sentinel模式的,代理层解决方案每接入一个同步任务就需要重新调整Redis架构和网络,对运维同学不太友好
- 代理层解决方案同样面临同步写其他机房还是异步写其他机房,写其他机房失败怎么处理的问题。
- 开源界的Redis代理项目基本都不是基于java语言的,对于我们团队来说二次开发的难度较大。
- 我们需要解析到客户端的指令
- 需要解决同步回环问题:A -> B -> A
四、实现细节
4.1 网络架构
4.2 同步回环

- 业务系统在A机房redis-A写入指令 set a 1
- A机房replicator-A作为redis-A的从节点接收到指令set a 1
- rotter-A将指令set a 1写入B机房redis-B
- B机房replicator-B作为redis-B的从节点接收到指令set a 1
- rotter-B将指令set a 1写入A机房redis-A …
- 业务系统在A机房redis-A写入指令 set a 1
- A机房replicator-A作为redis-A的从节点接收到指令set a 1
- rotter-A MD5(set a 1) 得到circle-key-md5,拼装成指令setex circle-key-md5 120 1
- rotter-A将指令setex circle-key-md5 120 1和指令set a 1一起写入B机房redis-B
- B机房replicator-B作为redis-B的从节点接收到指令setex circle-key-md5 120 1 和set a 1
- rotter-B直接忽略circle-key指令
- rotter-B在本机房执行del circle-key-md5,如果成功说明是回环KEY,不需要同步至A机房
4.3 高吞吐量
- Rotter收到同步指令之后需要在本机房执行del circle-key-md5来判断当前指令是否为循环指令
- Rotter将同步指令和circle-key-md5写入另一机房Redis
4.4 高堆积能力

- redisOffset(8字节):存储每条同步指令在复制积压缓冲区的offset,每次重新启动同步任务时可以通过二分查找确定是否需要从磁盘中继续读取指令。
- dataOffset(8字节):存储指定在磁盘文件中的位置
- dataLength(2字节):存储当前指令的长度
五、其他问题
5.1 Rotter连接业务Redis时造成Redis全量dump而影响业务系统
协议名
|
Redis版本
|
原理
|
问题
|
SYNC
|
2.8以下
|
每次都生成RDB文件,复制到slave节点
|
网络秒级抖动都会造成master bgsave,影响服务可用性
|
PSYNC
|
2.8及以上
|
引入复制积压缓冲区,当redis复制中断后,slave上报原master runid + 当前已同步master的offset会尝试批量同步
|
redis slave重启或者 redis master发生故障切换,slave需进行全量重同步。
|
PSYNC2
|
4.0及以上
|
用master_replid1(当前主从复制ID)和master_replid2(上一次主从复制ID)取代了runid,故障切换后master_replid2替换为master_replid1。
|
- slave发送Replication ID, offset到master
- master开启一个进程执行bgsave,生成RDB文件。在此期间所有新的指令都会缓存到当前slave的输出缓冲区中
- master把RDB文件发送到slave
- slave把RDB文件加载到内存
- master把输出缓冲区中的指令增量同步到slave
- 优先连接Redis从节点,减少bgsave对业务的影响
- 配置同步任务时可以选择是否忽略全量dump,当忽略全量dump时,Rotter会通过redis info命令拿到复制积压缓冲区的offset,从最新的位置开始增量同步。
5.2 如何防止Rotter同步反向污染源Redis数据

- 图5-2中第3步Rottor-A将del a指令同步到B机房之前,生成删除保护指令setex rotter:delete:a 120 1,将这两条指令都写入redis-B
- 图5-2中第6步Rotter-B同步指令set a oldValue先执行 exists rotter:delete:a,返回成功判定key a是刚被删除的,不会同步A机房
六、参考资料
禧云Redis跨机房双向同步实践的更多相关文章
- 原生Redis跨数据中心双向同步优化实践
一.背景 公司基于业务发展以及战略部署,需要实现在多个数据中心单元化部署,一方面可以实现多数据中心容灾,另外可以提升用户请求访问速度.需要保证多数据中心容灾或者实现用户就近访问的话,需要各个数据中心拥 ...
- 传统业务上云:跨AZ容灾架构解析
本文由 网易云发布. 数字化转型浪潮之下,采用云计算服务提升业务敏捷性.降低运维成本,成为了传统企业的优选方案.网易云资深解决方案架构师张亮通过某物流企业客户的实际案例,分享了传统业务系统在云上的架 ...
- redis跨实例迁移 & redis上云
1)redis跨实例迁移--源实例db11迁移至目标实例db30 root@fe2e836e4470:/data# redis-cli -a pwd1 -n 11 keys \* |while rea ...
- Redis 数据恢复方法,redis-port 工具将自建 redis 的 rdb文件同步到云数据库
1. Redis 恢复的机制 如果只配置 AOF ,重启时加载 AOF 文件恢复数据: 如果同时配置了 RDB 和 AOF ,启动是只加载 AOF 文件恢复数据: 如果只配置 RDB,启动是将加载 d ...
- 转: 微博的多机房部署的实践(from infoq)
转: http://www.infoq.com/cn/articles/weibo-multi-idc-architecture 在国内网络环境下,单机房的可靠性无法满足大型互联网服务的要求,如机房 ...
- 深度解析双十一背后的阿里云 Redis 服务
摘要: Redis是一个使用范围很广的NOSQL数据库,阿里云Redis同时在公有云和阿里集团内部进行服务,本文介绍了阿里云Redis双11的一些业务场景:微淘社区之亿级关系链存储.天猫直播之评论商品 ...
- Redis哨兵模式主从同步不可以绑定127.0.0.1或者0.0.0.0,不然无法进行主从同步
Redis哨兵模式主从同步不可以绑定127.0.0.1或者0.0.0.0,不然无法进行主从同步,一定要绑定内网IP,而对于跨机房的问题,可以使用iptables进行nat转发来解决.
- Linux实战教学笔记48:openvpn架构实施方案(一)跨机房异地灾备
第一章VPN介绍 1.1 VPN概述 VPN(全称Virtual Private Network)虚拟专用网络,是依靠ISP和其他的NSP,在公共网络中建立专用的数据通信网络的技术,可以为企业之间或者 ...
- 线上SpringCloud网关调用微服务跨机房了,咋整?
1.前言 公司内考虑到服务器资源成本的问题,目前业务上还在进行服务的容器化改造和迁移,计划将容器化后的服务,以及一些中间件(MQ.DB.ES.Redis等)尽量都迁移到其他机房. 那你们为什么不用阿里 ...
随机推荐
- 深入浅出分析 PriorityQueue
一.摘要 在前几篇文章中,咱们了解到,Queue 的实现类有 ArrayDeque.LinkedList.PriorityQueue. 在上一章节中,陆续的介绍到 ArrayDeque 和 Linke ...
- thinking in java 阅读收获
<thinking in java>,国内翻译为<JAVA编程思想>,一直听说该书写的非常好,今日研读,果然有所收获,特在此记录一些阅读时点点滴滴的收获. 1. “基本数据类 ...
- Unity中文API参考手册
转载请标明原文地址:http://www.cnblogs.com/zhangyukof/p/6835582.html Unity5中文脚本手册 网页版 Unity API 执行顺序: Unity5中 ...
- [answerer的算法课堂]简单描述4种排序算法(C语言实现)
[answerer的算法课堂]简单描述4种排序算法(C语言实现) 这是我第一次写文章,想要记录自己的学习生活,写得不好请包涵or指导,本来想一口气写好多种,后来发现,写太多的话反而可读性不强,而且,我 ...
- ES6 promise 使用示例
new Promise(function (resolve, reject) { $.ajax({ type : 'post', data : formData, dataType : 'json', ...
- Caffe源码-Net类(上)
Net类简介 Net类主要处理各个Layer之间的输入输出数据和参数数据共享等的关系.由于Net类的代码较多,本次主要介绍网络初始化部分的代码.Net类在初始化的时候将各个Layer的输出blob都统 ...
- AWVS 10.5使用指南
前言 AWVS是一款可与IBM AppScan比肩的.功能十分强大的Web漏洞扫描器.由Acunetix开发,官方站点提供了关于各种类型漏洞的解释和如何防范,具体参考:Acunetix Web Vul ...
- 高精度模板 val.1
目录 高精构造 结构体 char数组转高精: 高精加高精 高精乘单精 高精除单精 同样搬以前初三写的... 其实还有个val.2,搬到文章里去了 @ 在做一道斯特林数的时候被卡高精...于是滚来写一些 ...
- WFS服务查询方法
基于Geoserver发布的wfs服务,实现空间和属性信息的查询.wfs包含getFeature操作,用来检索要素信息,支持返回gml格式的地理要素表达. WFS的getFeature操作需要提供的参 ...
- VMware kali虚拟机环境配置
编译内核 (1)执行命令uname -r以查看内核版本. (2)执行命令apt-cache search linux-headers查看是否安装内核头文件. (3) 如果uname -r出现的内容在 ...