September 28, 2025
本文中使用的 Kafka 版本为 v3.3.2
引言
#
Kafka MirrorMaker2 是 Kafka 官方提供的跨集群数据复制工具, 它是基于 Kafka Connect 框架构建的。MirrorMaker2 支持多种部署模式, 包括 Dedicated 模式和 Connect 集群模式,还有 standalone 模式。
其中, Dedicated 模式有一个启动脚本 kafka-mirror-maker.sh
, 该脚本会启动一个独立的 MirrorMaker2 实例, 而不需要依赖 Kafka Connect 集群。Dedicated 模式适合小规模的复制任务, 但在大规模部署中, 它缺乏可扩展性和高可用性。
相比之下, Connect 集群模式则是先搭建出一个 Kafka Connect 集群, 再提交 MirrorMaker2
的 MirrorSourceConnector
任务。这种模式下, 可以通过增加或减少 Connect 工作节点来动态调整复制任务的资源, 具备更好的弹性和容错能力。
当然配置上也会更复杂一些, 需要管理 Connect 集群的配置和任务。
那么, 如果我们已经在使用 Dedicated 模式部署了 MirrorMaker2, 但现在需要切换到 Connect 集群模式, 应该如何操作呢? 本文将介绍从 Dedicated 模式迁移到 Connect 集群模式时,怎么处理已经同步的 offset 进度, 以确保数据的一致性和连续性。
...
March 29, 2020
redis主从复制是高可用方案中的一部分,那主从复制是如何进行的?又是如何实现的?怎么支撑了redis的高可用性?在主从模式下Master和Slave节点分别做了哪些事情?
redis高可用方案是什么?
#
我理解的redis高可用的特点有:
- 高QPS,主从 => 读写分离
- 高容量,集群分片 => 高容量
- 故障转移,sentinel => 故障转移
- 故障恢复,数据持久 => 故障恢复 ~ 这里我简单的理解(RDB + AOF)= 故障恢复
主从复制
#
redis 主从复制有两个版本:旧版(Ver2.8-),新版(Ver2.8+,增加PSYNC命令来解决旧版中的问题)
讨论复制时都需要考虑两种场景:
- 场景1:从节点刚刚上线,需要去同步主节点时,这部分可以理解为 全量复制。
- 场景2:从节点掉线,恢复上线后需要同步数据,使自己和主节点达到一致状态。这部分在旧版复制里等价于全量复制,在新版里可以理解为增量复制。
当然你肯定会想到如果主节点掉线,这时候会怎么样?这个场景当然也在redis高可用方案中,之时不是本文的重点,属于Sentinel机制的内容了。
旧版主从复制
#
前文说过了,旧版主从复制只有全量复制用于应付上述两个场景,因此下面的流程也只有一份:
- 从服务器向主服务器发送sync命令。
- 主服务器在收到sync命令之后,调用bgsave命令生成最新的rdb文件,将这个文件同步给从服务器,这样从服务器载入这个rdb文件之后,状态就会和主服务器执行bgsave命令时候的一致。
- 主服务器将保存在命令缓冲区中的写命令同步给从服务器,从服务器执行这些命令,这样从服务器的状态就跟主服务器当前状态一致了。
如果你不知道redis中还有个缓冲区的话,建议系统的了解下redis中缓冲区的设计。这里缓冲区特指命令缓冲区,后面还会讲到复制缓冲区。
但是这样的实现在 场景2 下的缺点很明显:如果说从节点断线后迅速上线,这段时间内的产生的写命令很少,却要全量复制主库的数据,传输了大量重复数据。
SYNC命令产生的消耗:
1. 主节点生成RDB,需要消耗大量的CPU,内存和磁盘IO
2. 网络传输大量字节数据,需要消耗主从服务器的网络资源
3. 从节点需要从RDB文件恢复,会造成阻塞无法接受客户端请求
优点就是:简单暴力。个人看来在redis架构中不合适的用法,不代表说实际场景中也一定不合适,简单暴力也是一个很大的优点。
新版主从复制
#
新版的主从复制跟旧版的区别就在于:对场景2的优化。
场景2的缺点上文已经提到过了,那么优化的方向就是**“尽量不使用全量复制;增加增量复制(PSYNC)的功能”**。为此还要解决下列问题:
- 如果某个从节点断线了,重新上线该从节点如何知道自己是否应该全量还是增量复制呢?
- 该从节点断线恢复后,又怎么知道自己缺失了哪些数据呢?
- 主节点又如何补偿该从节点在断线期间丢失的那部分数据呢?旧版的复制除了RDB,还有从命令缓冲区中的写命令来保持数据一致。
为此新版中使用了以下概念:
运行ID - runid
#
每个redis服务器都有其runid,runid由服务器在启动时自动生成,主服务器会将自己的runid发送给从服务器,而从服务器会将主服务器的runid保存起来。从服务器redis断线重连之后进行同步时,就是根据runid来判断同步的进度:
- 如果前后两次主服务器runid一致,则认为这一次断线重连还是之前复制的主服务器,主服务器可以继续尝试部分同步操作。
- 如果前后两次主服务器runid不相同,则全同步流程。
复制偏移量 - offset
#
主从节点,分别会维护一个复制偏移量:
主服务器每次向从服务器同步了N字节数据之后,将修改自己的复制偏移量+N。从服务器每次从主服务器同步了N字节数据之后,将修改自己的复制偏移量+N。通过对比主从节点的偏移量很容易就可以发现,主从节点是否处于一致状态。
...