4.4 高堆积能力
由于跨机房网络的不确定性,网络隔离随时可能发生 。为了保证同步指令不丢失,我们需要把指令写到磁盘文件中,等到网络恢复时再从磁盘队列读出来写到目标机房,
为了保证同步效率,我们这里使用的是磁盘和内存混合队列MixBlockingQueue
……
下面我们再来看看磁盘队列是怎么实现的
磁盘队列包含两个文件:数据文件和索引文件 。数据结构如图4-4
文章插图
图4-4
其中索引文件是定长的18字节:
- redisOffset(8字节):存储每条同步指令在复制积压缓冲区的offset,每次重新启动同步任务时可以通过二分查找确定是否需要从磁盘中继续读取指令 。
- dataOffset(8字节):存储指定在磁盘文件中的位置
- dataLength(2字节):存储当前指令的长度
五、其他问题
5.1 Rotter连接业务Redis时造成Redis全量dump而影响业务系统
背景知识一:复制积压缓冲区
复制积压缓冲区是一个保存在主节点的一个固定长度的先进先出的队列,默认大小 1MB 。这个队列在 slave 连接时创建 。这时主节点响应写命令时,不但会把命令发送给从节点,也会写入复制缓冲区 。他的作用就是用于部分复制和复制命令丢失的数据补救 。通过 info replication 可以看到相关信息 。
背景知识二:Redis主从同步协议
文章插图
背景知识三:Redis全量同步流程
- slave发送Replication ID, offset到master
- master开启一个进程执行bgsave,生成RDB文件 。在此期间所有新的指令都会缓存到当前slave的输出缓冲区中
- master把RDB文件发送到slave
- slave把RDB文件加载到内存
- master把输出缓冲区中的指令增量同步到slave
我们的解决方案有两点:
- 优先连接Redis从节点,减少bgsave对业务的影响
- 配置同步任务时可以选择是否忽略全量dump,当忽略全量dump时,Rotter会通过redis info命令拿到复制积压缓冲区的offset,从最新的位置开始增量同步 。
Redis数据同步和MySQL数据同步是相互独立的,当MySQL同步延时较大时可能会出现Redis数据反向污染的情况 。案例如下:
文章插图
图5-2
如图5-2流程所示,Rotter同步会造成业务系统原本已经A机房删掉了记录a又被同步到A机房Redis了 。
为了解决这个问题,我们引入了删除保护的概念:一段时间(默认2分钟)内在A机房删除的数据不会从B机房同步到A机房 。具体做法如下:
- 图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机房
原文出处: http://www.cnblogs.com/zhengyun_ustc/p/rotter.html
推荐阅读
- 海门树勋镇,千亩金银花基地促推农业新跨越
- 茶产业大发展助推遵义实现经济大跨越
- 乐山,发展峨眉山茶 助推农业大跨越
- Windows下php安装redis扩展
- 2022五一能去跨省去三亚玩吗,五一去三亚是否合适
- 品牌兴茶 实现茶企跨越式发展
- Redis消息队列:RPOPLPUSH vs Pub/Sub
- 单向 mysql:Otter跨机房数据同步
- 保靖,中国黄金茶之乡的茶业跨越式发展
- 福建上杭蛟潭村,高山种茶推进跨越式发展