专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

关于Redis的主从复制

:::tip

SLAVEOF host:port 命令可以将当前服务器去复制目标服务器,进行复制中的主从服务器的数据库将保存相同的数据,概念上称为数据库状态一致

:::

旧版复制功能

同步(sync)

当从服务器发送SLAVEOF命令要求复制主服务器时,从服务器首先执行同步操作,即将从服务器的数据库状态更新至主服务器当前所处的数据库状态,具体步骤如下

1、 从服务器发送SYNC命令
2、 收到命令的主服务执行BGSAVE命令,在后台生成RDB文件,并使用缓冲区记录从现在执行BGSAVE之后执行的所有写命令
3、 主服务器执行完BGSAVE之后,主服务器会将RDB文件发送给从服务器,从服务器接收并载入这个RDB文件
4、 主服务器将记录在缓冲区的所有写命令发送给从服务器,从服务器执行这些写命令

77_1.png

命令传播(command propagate)

同步操作完成后,主从服务器目前的数据库状态达到一致,但这种状态不是一成不变的,每当主服务器执行客户端发送的写命令时,主从服务器的数据库就不再一致

所以为了保持主从服务器的数据一致,主服务器需要对从服务器执行命令传播:将写命令发送给从服务器,当从服务也执行完后,主从服务器将再次回到一致状态

77_2.png

缺陷

旧版复制功能的缺陷主要体现在从服务器断线重连的处理

77_3.png

如上图的情况,从服务器在某一刻断线,再此期间主服务器增加了k3,k4两个键,按目前的实现逻辑,从服务器在之后重连后,依旧是再次发送SYNC命令进行同步(主服务器生成和发送RDB文件给从服务器载入)

但其实从服务器主需要断线期间的k3,k4键即可,RDB文件中的其他键信息对从服务器来说都是不必要的

:::tip

SYNC是一个非常耗资源的操作

1、 主服务器需要执行BGSAVE来生成RDB文件,这耗费CPU,内存和磁盘IO资源
2、 主服务器需要将RDB发送给从服务器,这耗费网络带宽
3、 从服务器加载RDB文件时会阻塞其他命令的处理

:::

新版复制功能

PSYNC命令替代SYNC

为了解决断线重连后的重同步问题,Redis2.8以后使用了PSYNC代替SYNC进行同步操作,有以下两种模式:

1、 完整重同步:用于初次复制,执行步骤与SYNC基本一致。 PSYNC ? -1
2、 部分重同步:用于断线重连后的重复制,在条件允许的情况下,只需要将断开期间主服务器的写命令发送给从服务器 。PSYNC runid offset

以下是执行部分重同步时的通信过程

77_4.png

部分重同步的工作原理

部分重同步主要由三个部分组成

1、 主服务器的复制偏移量和从服务器的复制偏移量
2、 主服务器的复制积压缓冲区
3、 服务器的运行ID

复制偏移量

每一个服务器都会分别维护一个复制偏移量:

1、 主服务每次向从服务器传播N个字节的数据(写命令)时,就将自己的复制偏移量加N
2、 从服务每次收到主服务器传播的N个字节的数据(写命令)时,就将自己的复制偏移量加N

77_5.png 77_6.png

那么通过对比主从服务器的复制偏移量就可以知道

1、 它们目前的状态是否一致
2、 它们之间缺失了多少数据

77_7.png

复制积压缓冲区

通过复制偏移量可以知道主从服务器之间缺失了多少数据,那么缺失的数据是什么?要去哪里找回来呢?

这里就用上了复制积压缓冲区了

当主服务器进行命令传播时,它不仅将写命令发送给所有从服务器,还会将写命令放进一个固定长度的先进先出的队列里,这个队列就是复制积压缓冲区(默认大小是1MB)

77_8.png

当从服务器重连后,从服务器通过PSYNC命令将自己的复制偏移量发送给主服务器

1、 如果从服务器复制偏移量之后的数据还在复制积压缓冲区中,那么进行部分重同步的操作
2、 如果从服务器复制偏移量之后的数据不在复制积压缓冲区中,那么进行完整重同步的操作

:::tip

如何调整复制积压缓冲区的大小

通过redis.conf中的repl-backlog-size进行调整

一般调整为 2 * 断线重连所需的平均秒数 * 主服务器每秒产生的写命令数量

:::

服务器运行ID

:::tip

每个Redis服务器都拥有自己的运行ID

运行ID由服务器启动时生成,由40个随机的十六进制字符组成

:::

初次复制时,从服务器会保存主服务器的运行ID

当从服务器断线重连时,从服务器将这个运行ID发送给主服务器:

1、 如果与主服务器的运行ID相同,则说明断线前复制的就是当前连接的主服务器,主服务器可以根据条件尝试进行部分重同步
2、 如果与主服务器的运行ID不同,则说明断线前复制的不是当前连接的主服务器,主服务器将对从服务器进行完整重同步

PSYNC执行时可能遇上的情况

77_9.png

从服务器执行SLAVEOF的完整过程

1、 设置主服务器的地址和端口
2、 与主服务器建立套接字连接
3、 发送PING命令
4、 身份验证
5、 向主服务器发送从服务器端口信息 REPLCONF listening-port 6、 同步
7、 命令传播

心跳检测

:::tip

在命令传播阶段,从服务器默认一秒一次的速率,向主服务器发送指令

REPLCONF ACK <replication_offset>

其中replication_offset时从服务器当前的复制偏移量

:::

发送REPLCONF ACK命令主要由三个作用:

1、 检测主从服务器的连接状态
2、 辅助实现min-slaves配置选项
3、 检测命令丢失

参考

1、 Redis设计与实现

文章永久链接:https://tech.souyunku.com/26020

未经允许不得转载:搜云库技术团队 » 关于Redis的主从复制

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们