Redis主从复制

Redis的主从复制是指一个Redis实例(主节点)可以将数据复制到一个或多个从节点,从节点从主节点获取数据并保持同步

复制流程

  • 开始同步:从节点通过向主节点发送PSYNC命令发起同步
  • 全量复制:如果是第一次连接或之前的连接失效,从节点会请求全量复制,主节点将当前数据快照(RDB文件)发送给从节点
  • 增量复制:全量复制完毕后,主从之间会保持一个长连接,主节点会通过这个连接将后续的写操作传递给从节点执行,来保证数据的一致

Redis主从架构

image-20250403084854669.png

主从架构可以实现读写分离

写操作可以请求主节点,读操作之请求从节点,这样就能减轻主节点的压力
image-20250403085157968.png

整个主从集群仅主节点可以写入,其他从节点都通过复制来同步数据,这样就能保证数据的一致性。并且对请求分散到多个从节点,提高了Redis的吞吐量,从一定程度上也提高了Redis的可能性

主从复制原理

Redis之间主从复制主要有两种数据同步方式,分别是全量同步和增量同步

1)全量同步
image-20250403090908215.png

  • runid指的是主服务器的run ID,从节点第一次同步不知道主节点ID,于是传递 ?
  • offset为复制进度,第一次同步值为 -1

文字版流程

  • 从节点发送psync ? -1 ,触发同步
  • 主节点收到从节点的 psync 命令之后,发现 runid 没值,判断是全量同步,返回 fullresync 并带上主服务器的 runid 和当前复制进度,从服务器会存储这两个值
  • 主节点执行 bgsave 生成 RDB 文件,在 RDB 文件生成过程中,主节点新接收到的写入数据命令会存储到 replication buffer 中
  • RDB文件生成完毕后,主节点将其发送给从节点,从节点清空旧数据,加载RDB的数据
  • 等到从节点中RDB文件加载完成后,主节点将replication buffer缓存的数据发送给从节点,从节点执行命令,保证数据的一致性

待同步完毕后,主从之间会保持一个长连接,主节点会通过这个连接将后续的写操作传递给从节点执行,来保证数据的一致

2)增量同步

主从之间的网络可能不稳定,如果连接断开,主节点部分数据未传递给从节点执行,主从数据就不一致了

此时有一种选择是再次发起全量同步,但是全量同步数据量比较大,非常耗时。因此 Redis在2.8版本引入了增量同步,仅需把连接断开期间的数据同步给从节点就好了,此时需要介绍一下 repl\_backlog\_buffer

repl\_backlog\_buffer是一个环形缓冲区,默认大小为1m。主节点会将写入命令存到这个缓冲区,但是大小有限,待写入的命令超过1m后,会覆盖之前的数据,因此是环形写入

增量同步也是 psync 命令,如果主节点判断从节点传递的runid和主节点一致,且根据offset判断数据还在repl\_backlog\_buffer中,则说明可以进行增量同步

于是就去repl\_backlog\_buffer查找对应offset之后的命令数据,写入到replication buffer中,最终将其发送给slave节点,salve节点收到指令对应的命令,一次增量同步过程就完成了
image-20250403092437621.png

如果根据offset判断数据已经被覆盖了,此时只能触发全量同步

因此可以调整repl\_backlog\_buffer大小,尽量避免出现全量同步

replication buffer和repl\_backlog\_buffer的区别

因为不同的从节点同步速度不一样,主节点会为每个从节点都创建一个replication buffer,它用于实时传输写命令,且大小是动态的,因为对于同步速度较慢的从服务器,需要更多的内存来缓存数据

虽说replication buffer没有明确的大小限制,但是可以通过client-output-buffer-limit间接控制,该参数可以设置不同类型客户端的输出缓冲区限制

当缓冲区大小超过限制时,Redis会断开与客户端的连接

client-output-buffer-limit slave 256mb 64mb 60

上述配置表示,如果从服务器的输出缓冲区大小超过256mb或超过64mb的时间达到60s,Redis将断开从服务的连接

repl\_backlog\_buffer在主节点上只有一个,存储最新的写命令,用于从服务器重新连接时进行部分重同步

最后修改:2025 年 04 月 03 日
如果觉得我的文章对你有用,请随意赞赏