五、Redis主从同步
Redis 主从同步
- 一、复制
- 二、旧版复制功能的实现
- 2.1、同步操作
- 2.2、命令传播操作
- 三、旧版复制功能的缺陷
- 四、新版复制功能的实现
- 五、部分重同步的实现
- 5.1、复制偏移量
- 5.2、复制积压缓存区
- 5.3、服务器运行 ID
- 六、PSYNC 命令的实现
- 七、复制的实现
- 7.1、步骤1:设置主服务器的地址和端口
- 7.2、步骤2:建立套接字连接
- 7.3、步骤3:发送 PING 命令
- 7.4、步骤4:身份验证
- 7.5、步骤5:发送端口信息
- 7.6、步骤6:同步
- 7.7、步骤7:命令传播
- 八、心跳检测
- 8.1、检测主从服务器的网络连接状态
- 8.2、辅助实现 min-slaves 配置选项
- 8.3、检测命令丢失
一、复制
在 Redis 中,用户可以通过执行 SLAVEOF
命令或者选项,让一个服务器去复制另一个服务器,我们称呼为主服务器,而对主服务器进行复制的服务器则被称为从服务器
两个 Redis 服务器,地址分别是 127.0.0.1:6379
和 127.0.0.1:12345
,如果我们向服务器 127.0.0.1:12345
发送以下命令:
127.0.0.1:12345> SLAVEOF 127.0.0.1 6379
OK
那么服务器 127.0.0.1:12345
将成为 127.0.0.1:6379
的从服务器
二、旧版复制功能的实现
Redis 的复制功能分为同步操作和命令传播操作:
- 同步操作:用于将从服务器的数据库状态更新至主服务器当前所处的数据库状态
- 命令传播操作:用于当主服务器的数据库状态被修改,导致主从服务器的数据库状态出现不一致时,让主从服务器的数据库重新回到一致
2.1、同步操作
当客户端向从服务器发送 SLAVEOF
命令,要求从服务器复制主服务器时,从服务器首先需要执行同步操作,也就是说,将从服务器的数据库状态更新至主服务器当前所处的数据库状态
从服务器对主服务器的同步操作需要通过向主服务器发送 SYNC 命令来完成,以下是 SYNC 命令的执行步骤:
- 从服务器向主服务器发送
SYNC
命令 - 收到
SYNC
命令的主服务器执行BGSAVE
命令,在后台生成一个 RDB 文件,并使用一个缓冲区记录从现在开始执行的所有写命令 - 当主服务器的
BGSAVE
执行完毕时,主服务器会将BGSAVE
命令生成的 RDB 发送给从服务器,从服务器接收并载入这个 RDB 文件,将自己的数据库状态更新至主服务器执行BGSAVE
命令时的数据库状态 - 主服务器将记录在缓冲区里面的所有写命令发送给从服务器,从服务器执行这些写命令,将自己数据库状态更新至主服务器当前所处的状态
举例说明主从服务器同步的过程
时间 | 主服务器 | 从服务器 |
---|---|---|
T0 | 服务器启动 | 服务器启动 |
T1 |
执行 SET k1 v1
|
|
T2 |
执行 SET k2 v2
|
|
T3 |
执行 SET k3 v3
|
|
T4 |
向主服务器发送 SYNC 命令
|
|
T5 |
接收到从服务器发送来的 SYNC 命令,执行 BGSAVE 命令,创建包含 k1,k2,k3 的 RDB 文件。并使用缓冲区记录记录接下来执行的所有写命令
|
|
T6 |
执行 SET k4 v4 ,并将这个命令记录到缓冲区里面
|
|
T7 |
执行 SET k5 v5 ,并将这个命令记录到缓冲区里面
|
|
T8 |
BGSAVE 命令执行完毕,向从服务器发送 RDB 文件
|
|
T9 | 接收并载入主服务器发送来的 RDB 文件,获得 k1,k2,k3 三个键 | |
T10 |
向从服务器发送缓存区保存的写命令 SET k4 v4 和 SET k5 v5
|
|
T11 | 接收并执行主服务器发来的连个 SET 命令,得到 k4 和 k5 两个键 | |
T12 | 同步完成,现在主从服务器两者的数据都包含了 k1,k2,k3,k4 和 k5 | 同步完成,现在主从服务器两者的数据都包含了 k1,k2,k3,k4 和 k5 |
2.2、命令传播操作
在同步操作执行完毕之后,主从服务器两者的数据库将达到一致状态,但这种一致不是一成不变的。每当主服务器执行客户端发送的写命令时,主服务器的数据库就有可能会被修改,并导致主从服务器状态不再一致
处于不一致状态的主从服务器
为了让主从服务器再次回到一致状态,主服务器需要对从服务器执行命令传播操作:主服务器会将自己执行的写命令,也即是造成主从服务器不一致的那条写命令,发送给从服务器执行,当从服务器执行了相同的写命令之后,主从服务器再次回到一致状态
在上面的例子中,主服务器因为执行了命令 DEL k2
而导致主从服务器不一致,所以主服务器将向从服务器发送相同的命令 DEL k2
。当从服务器执行完这个命令之后,主从服务器将再次回到一致状态,现在主从服务器两者的数据库都不再包含键 k2 了
三、旧版复制功能的缺陷
在 Redis 中,从服务器对主服务器的复制可以分为以下两种情况:
- 初次复制:从服务器以前没有复制过任何主服务器,或者从服务器当前要复制的主服务器和上一次复制的主服务器不同
- 断线后重复制:处于命令传播阶段的主从服务器因为网络原因而中断了复制,但从服务器通过自动重连接重新连上了主服务器,并继续复制主服务器
对于初次复制来说,旧版复制功能能够很好的完成任务,但对于断线后复制来说,旧版复制功能虽然也能让主从服务器重新回到一致状态,但效率却非常低
时间 | 主服务器 | 从服务器 |
---|---|---|
T0 | 主从服务器完成同步 | 主从服务器完成同步 |
T1 |
执行并传播 SET k1 v1
|
执行主服务器传来的 SET k1 v1
|
T2 |
执行并传播 SET k2 v2
|
执行主服务器传来的 SET k2 v2
|
… | … | … |
T10085 |
执行并传播 SET k10085 v10085
|
执行主服务器传来的 SET k10085 v10085
|
T10086 |
执行并传播 SET k10086 v10086
|
执行主服务器传来的 SET k10086 v10086
|
T10087 | 主从服务器连接断开 | 主从服务器连接断开 |
T10088 |
执行 SET k10087 v10087
|
断线中,尝试重新连接主服务器 |
T10089 |
执行 SET k10088 v10088
|
断线中,尝试重新连接主服务器 |
T10090 |
执行 SET k10089 v10089
|
断线中,尝试重新连接主服务器 |
T10091 | 主从服务器重新连接 | 主从服务器重新连接 |
T10092 |
向主服务器发送 SYNC 命令
|
|
T10093 |
接收到从服务器发来的 SYNC 命令,执行 BGSAVE ,创建包含 k1 至 k10089 的 RDB 文件,并使用缓冲区记录接下来执行的所有写命令
|
|
T10094 |
BGSAVE 命令执行完毕,向从服务器发送 RDB 文件
|
|
T10095 | 接收主服务器发来的 RDB 文件,获取键 k1 至 k10089 | |
T10096 |
因为在 BGSAVE 命令执行期间,主服务器没有执行任何写命令,所以跳过发送缓冲区包含的写命令这一步
|
|
T10097 | 主从服务器再次完成同步 | 主从服务器再次完成同步 |
在时间 T10091,从服务器终于重新连上主服务器,因为这时主从服务器的状态已经不再一致,所以从服务器将向主服务器发送 SYNC
命令,而主服务器会将键 k1 至 k10089 的 RDB 文件发送给从服务器,从服务器通过接收和载入这个 RDB 文件来将数据库更新至主服务器数据库所处的状态。
虽然再次发送 SYNC 命令可以让主从服务器重新回到一致状态,但如果我们仔细研究这个断线重复制过程,就会发现传送 RDB 文件这一步实际上并不是非做不可的:
- 主服务器在时间 T0 至时间 T10086 中一致处于一致状态,这两个服务器保存的数据大部分都是相同的
- 从服务器想要将自己更新至主服务器当前所处的状态,真正需要的是主从服务器连接终端期间,主服务器新添加的 k10087、k10088、k10089 三个键的数据
- 可惜的是,旧版复制功能并没有利用上述两点,而是继续让主服务器生成并向服务器发送包含键 k1 至键 k10089 的 RDB 文件,但实际上 RDB 文件包含的键 k1 至 k10086 的数据对于从服务器来说都是不必要的
上面给出的例子可能有一点理想化,因为在主从服务器断线期间,主服务器执行的写命令可能成百上千之多,而不仅仅是这三个写命令。但总的来说,主从服务器断开的时间越短,主服务器在断线期间执行的写命令就越少,而执行少量写命令产生的数据量通常比整个数据库数据量要少得多。在这种情况下,为了让从服务器弥补这一小部分缺失的数据,却要让主从服务器重新执行一次 SYNC 命令,这种做法无疑是非常低效的
SYNC 命令是一个非常耗费资源的操作,每次执行 SYNC 命令,主从服务器需要执行以下操作:
- 主服务器需要执行 BGSAVE 命令来生成 RDB 文件,这个生成操作会耗费主服务器大量的 CPU、内存和磁盘 I/O 资源
- 主服务器需要将自己生成的 RDB 文件发送给从服务器,这个发送操作会耗费主服务器大量的网络资源(带宽和流量),并对主服务器响应命令请求的时间产生影响
- 接收到 RDB 文件的服务器需要载入主服务器发来的 RDB 文件,并且在载入期间,从服务器会阻塞而没法处理命令请求
因为 SYNC
命令时一个如此耗费资源的操作,所以 Redis 有必要保证在真正有需要时才执行 SYNC
命令
四、新版复制功能的实现
为了解决旧版复制功能在处理断线重复制情况时的低效,Redis 从 2.8 版本开始使用 PSYNC
命令代替 SYNC
命令来执行复制时的同步操作
PSYNC
命令具有完整重同步和部分重同步两种模式:
- 完整重同步:用于处理初次复制情况:完整重同步的执行步骤和
SYNC
命令的执行步骤基本一致。都是通过让主服务器创建并发送RDB
文件,以及向从服务器发送保存在缓冲区里面的写命令来进行同步 - 部分重同步:用于处理断线后重复制情况:当从服务器在断线后重新连接主服务器时,如果条件允许,主服务器可以将主从服务器连接断开期间执行的写命令发送给从服务器,从服务器主要接收并执行这些命令,就可以将数据库状态更新至主服务器当前所处的状态
PSYNC 命令的部分重同步解决了旧版复制功能在处理断线后重复制时出现的低效情况:
时间 | 主服务器 | 从服务器 |
---|---|---|
T0 | 主从服务器完成同步 | 主从服务器完成同步 |
T1 |
执行并传播 SET k1 v1
|
执行主服务器传来的 SET k1 v1
|
T2 |
执行并传播 SET k2 v2
|
执行主服务器传来的 SET k2 v2
|
… | … | … |
T10085 |
执行并传播 SET k10085 v10085
|
执行主服务器传来的 SET k0085 v10085
|
T10086 |
执行并传播 SET k10086 v10086
|
执行主服务器传来的 SET k0086 v10086
|
T10087 | 主从服务器连接断开 | 主从服务器连接断开 |
T10088 |
执行并传播 SET k10087 v10087
|
断线中,尝试重新连接主服务器 |
T10089 |
执行并传播 SET k10088 v10088
|
断线中,尝试重新连接主服务器 |
T10090 |
执行并传播 SET k10089 v10089
|
断线中,尝试重新连接主服务器 |
T10091 | 主从服务器重新连接 | 主从服务器重新连接 |
T10092 |
向主服务器发送 PSYNC 命令
|
|
T10093 |
向从服务器 返回 +CONTINUE 回复,表示执行部分重同步
|
|
T10094 |
接收 +CONTINUE 回复,准备开始执行部分重同步
|
|
T10095 |
向从服务器发送 SET k10087 v10087 、SET k10088 v10088 、SET k10089 v10089 三个命令
|
|
T10096 |
接收并执行主服务器传来的三个 SET 命令
|
|
T10097 | 主从服务器再次完成同步 | 主从服务器再次完成同步 |
执行 SYNC
命令需要生成、传送和载入整个 RDB 文件,而部分重同步只需将从服务器缺少的写命令发送给从服务器执行就可以了
五、部分重同步的实现
部分重同步功能由一下三个部分组成:
- 主服务器的复制偏移量和从服务器的复制偏移量
- 主服务器的复制积压缓冲区
- 服务器的运行 ID
5.1、复制偏移量
执行复制的双方 – 主服务器和从服务器会分别维护一个复制的偏移量:
- 主服务器每次向从服务器传播 N 个字节的数据时,就将自己的复制偏移量的值加上 N
- 从服务器每次收到主服务器传播来的 N 个字节的数据时,就将自己的复制偏移量的值加上 N
如图所示的例子中,主从服务器的复制偏移量的值都是 10086
如果这时主服务器向三个从服务器传播长度为 33 字节的数据,那么主服务器的复制偏移量将更新为 10086 + 33 = 10119,而三个从服务器在接收到主服务器的数据之后,也会将复制偏移量更新为 10119
通过对比主从服务器的复制偏移量,程序可以很容易判断主从服务器是否一致状态:
- 如果主从服务器处于一致状态,那么主从服务器两者的偏移量总是相同的
- 如果主从服务器两者的偏移量不相同,那么说明主从服务器并未处于一致状态
主从服务器当前的复制偏移量都是 10086,但是就在主服务器要向从服务器传播长度为 33 字节的数据之前,从服务器 A 断线了,那么主服务器传播的数据将只有从服务器 B 和从服务器 C 能收到,在这之后,主服务器、从服务器 B 和从服务器 C 的复制偏移量都将更新为 10119,而断线的从服务器 A 的复制偏移量还是 10086,这说明从服务器 A 和主服务器并不一致
5.2、复制积压缓存区
复制积压缓冲区是由主服务器维护的一个固定长度先进先出队列,默认大小为 1MB
固定长度先进先出队列:当入队元素的数量大于队列长度时,最先入队的元素会被弹出,而新元素会被放入队列尾部
当主服务器进行命令传播时,它不仅会将写命令发送给所有从服务器,还会将写命令入队到复制积压缓冲区里面
因此,主服务器的复制积压缓存区保存着一部分最近传播的写命令,并且复制积压缓冲区会为队列中的每个字节记录相应的复制偏移量,类似于下表所示:
偏移量 | … | 10087 | 10088 | 10089 | 10090 | 10091 | 10092 | 10093 | 10094 | 10095 | 10096 | 10097 | … |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
字节值 | … |
'*'
|
3 |
'\r'
|
'\n
|
'$'
|
3 |
'\r'
|
'\n
|
'S'
|
'E'
|
'T'
|
当从服务器重连接上主服务器时,从服务器会通过 PSYNC
命令将自己的复制偏移量 offset 发送给主服务器,主服务器会根据这个复制偏移量来决定从服务器执行何种同步操作:
- 如果 offset 偏移量之后的数据,仍然存在于复制积压缓冲区里面,那么主服务器将对从服务器执行部分重同步操作
- 相反,如果 offset 偏移量之后的数据已经不存在于复制积压缓冲区,那么主服务器将对从服务器执行完整重同步操作
可以根据需要调整复制积压缓冲区的大小:
复制积压缓冲区的最小大小可以根据公式
second * write_size_per_second
来估算
- second:从服务器断线后重新连接上主服务器所需的平均时间(以秒计算)
- write_size_per_second:主服务器平均每秒产生的写命令数据量
例如:如果主服务器平均每秒产生 1 MB 的写数据,而从服务器断线之后平均要 5 秒才能重新连上主服务器,那么复制积压缓冲区的大小就不能低于 5 MB
为了安全起见,可以将复制积压缓冲区的大小设为 2 * second * write_size_per_second
,这样可以保证绝大部分断线情况都能用部分重同步来处理
5.3、服务器运行 ID
除了复制偏移量和复制积压缓冲区之外,实现部分重同步还需要用到服务器运行 ID
- 每个 Redis 服务器,不论主服务器还是从服务器,都会有自己的运行 ID
- 运行 ID 在服务器启动时自动生成,由 40 个随机的十六进制字符组成
当从服务器对主服务器进行初次复制时,主服务器会将自己的运行 ID 传送给从服务器,而从服务器则会将这个运行 ID 保存起来
当从服务器断线并重新连上一个主服务器时,从服务器会将向当前连接的主服务器发送之前保存的运行 ID
- 如果从服务器保存的运行 ID 和当前连接的主服务器的运行 ID 相同,那么说明从服务器断线之前复制的就是当前连接的主服务器。主服务器可以继续尝试执行部分重同步操作
- 相反的,如果从服务器保存的运行 ID 和当前连接的主服务器的运行 ID 不相同,那么说明从服务器断线之前复制的主服务器并不是当前连接的这个主服务器,主服务器将对从服务器执行完整重同步操作
六、PSYNC 命令的实现
PSYNC 命令的调用方法有两种:
- 如果从服务器以前没有复制过任何主服务器,或者之前执行过
SLAVEOF no one
命令,那么从服务器在开始一次新的复制时将向主服务器发送PSYNC ? -1
命令,主动请求主服务器进行完整重同步 - 如果从服务器已经复制过某个主服务器,那么从服务器在开始一次新的复制时将向主服务器发送
PSYNC <runid> <offset>
命令,其中,runid
是上一次复制的主服务器 ID,offset 则是从服务器当前的复制偏移量,接收到这些命令的主服务器会通过这两个参数来判断应该对从服务器执行哪种同步操作
根据情况,接收到 PSYNC 命令的主服务器会向同服务器返回以下三种回复的其中一种:
- 如果主服务器返回
+FULLRESYNC <runid> <offset>
回复,那么表示主服务器将与从服务器执行完整重同步操作:其中runid
是这个主服务器的运行 ID,从服务器会将这个 ID 保存起来,在下一次发送PSYNC
命令时使用;而offset
则是主服务器当前的复制偏移量,从服务器会将这个值作为自己的初始化偏移量 - 如果主服务器返回
+CONTINUE
回复,那么表示主服务器将与从服务器执行部分重同步操作,从服务器只要等着主服务器将自己缺少的那部分数据发送过来就可以了 - 如果主服务器返回
-ERR
回复,那么表示主服务器的版本低于 Redis 2.8,它识别不到PSYNC
命令,从服务器将向主服务器发送SYNC
命令,并与主服务器执行完整同步操作
下面流程图总结了 PSYNC 命令执行完整重同步和部分重同步时可能遇上的情况:
看一个完整的复制–网络中断–重复制的例子:
七、复制的实现
通过向从服务器发送 SLAVEOF
命令,可以让一个服务器去复制一个主服务器
7.1、步骤1:设置主服务器的地址和端口
当客户端向从服务器发送一下命令时:
127.0.0.1:12345> SLAVEOF 127.0.0.1 6379
OK
从服务器首先要做的就是将客户端给定的主服务器 IP 地址 127.0.0.1 以及端口 6379 保存到服务器状态的 masterhost
属性和 masterport
属性里面
struct redisSerer {// ...// 主服务器的地址char *masterhost;// 主服务器的端口int masterport;// ...
}
7.2、步骤2:建立套接字连接
在 SLAVEOF
命令执行之后,从服务器将根据命令所属的 IP 地址和端口,创建连向主服务器的套接字连接
如果从服务器创建的套接字连接能成功连接主服务器,那么从服务器将为这个套接字关联一个专门用于处理复制工作的文件处理器,这个处理器将负责后续的复制工作,比如接收 RDB 文件,以及接收主服务器传播来的写命令等
主服务器在接收从服务器的套接字连接之后,将为该套接字创建相应的客户端状态,并将从服务器看作是一个连接主服务器的客户端来对待,这时,从服务器将同时具备服务器和客户端两个身份:从服务器可以向主服务器发送命令请求,而主服务器则会向从服务器返回命令回复
7.3、步骤3:发送 PING 命令
从服务器成为主服务器的客户端之后,做的第一件事就是向主服务器发送一个 PING
命令,这个PING
命令有两个作用:
- 虽然主从服务器成功建立起了套接字连接,但双方并未使用套接字进行过任何通信,通过发送
PING
命令可以检查套接字的读写状态是否正常 - 因为复制工作接下来的几个步骤都必须在主服务器可以正常处理命令请求的状态下才能进行,通过发送
PING
命令可以检查主服务器能否正常处理命令请求
从服务器在发送 PING
命令时可能遇上的情况:
7.4、步骤4:身份验证
从服务器在收到主服务器返回的 “POST” 回复之后,下一步要做的就是决定是否进行身份验证;如果从服务器设置了 masterauth,那么进行身份验证
在需要进行身份验证的情况下,从服务器将向主服务器发送一条 AUTH
命令,命令的参数为从服务器 masterauth
选项的值
例如:从服务器 masterauth
选项的值为 10086,那么从服务器将向主服务器发送命令 AUTH 10086
从服务器在身份验证阶段可能遇到的情况有以下几种:
- 如果主服务器没有设置
requirepass
选项,并且从服务器也没用设置masterauth
选项,那么主服务器将继续执行从服务器发送的命令,复制工作可以继续进行 - 如果从服务器通过
AUTH
命令发送的密码和主服务器requirepass
选项所设置的密码相同,那么主服务器将继续执行从服务器发送的命令,复制工作可以继续进行,否则,主服务器将返回一个 invalid password 选项 - 如果主服务器设置了
requirepass
选项,但从服务器却没有设置masterauth
选项,那么主服务器将返回一个NOAUTH
错误;如果主服务器没有设置requirepass
选项,但从服务器却设置了masterauth
选项,那么主服务器将返回一个no password is set
错误
7.5、步骤5:发送端口信息
在身份验证步骤之后,从服务器将执行 REPLCONF listening-port <port-number>
,向主服务器发送从服务器的监听端口
例如:从服务器监听的端口为 12345,那么从服务器将向主服务器发送命令 REPLICONF listening-port 12345
主服务器在接收到这个命令之后,会将端口号记录在从服务器所对应的客户端状态的 slave_listening_port
属性中:
typedef struct redisClient {// ...// 从哪服务器的监听端口号int slave_listening_port;// ...
} redisClient;
slave_listening_port
属性目前唯一的作用就是在主服务器执行 INFO replication
命令时打印出从服务器的端口号
以下是客户端向例子中的主服务器发送 INFO replication
命令时得到的回复,其中 slave0
行的 port
域显示的就是从服务器对应客户端状态的 slave_listening_port
属性的值
127.0.0.1:6379> INFO replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=12345,status=online,offset=1289,lag=1
master_repl_offset:1289
...
7.6、步骤6:同步
在这一步,从服务器将向主服务器发送 PSYNC
命令,执行同步操作,并将自己的数据库更新至主服务器数据库当前所处的状态
7.7、步骤7:命令传播
当完成了同步之后,主从服务器就会进入命令传播阶段,这是主服务器只要一直将自己执行的写命令发送给从服务器,而从服务器只要一直接收并执行主服务器发来的写命令,就可以保证主从服务器保持一致了
八、心跳检测
在命令传播阶段,从服务器默认会以每秒一次的频率,向主服务器发送命令:REPLCONF ACK <replication_offset>
,其中 replication_offset
是从服务器当前的复制偏移量;发送 REPLCONF_ACK
命令对于主从服务器有三个作用:
- 检测主从服务器的网络状态
- 辅助实现
min-slaves
选项 - 检测命令丢失
8.1、检测主从服务器的网络连接状态
主服务器可以通过发送和接收 REPLCONF ACK 命令来检查两者之间的网络连接是否正常;如果主服务器超过一秒钟没有收到从服务器发来的 REPLCONF ACK 命令,那么主服务器就知道主从服务器之间的连接出问题了
通过向主服务器发送 INFO replication
命令,在列出的从服务器列表的 lag
一栏中,我们可以看到相应从服务器最后一次向主服务器发送 REPLCONF ACK
命令距离现在过了多少秒:
127.0.0.1:6379> INFO replication
role:master
connected_slaves:2
# 刚刚发送过 REPLCONF ACK 命令
slave0:ip=127.0.0.1,port=12345,status=online,offset=211,lag=0
# 15秒之前发送过 REPLCONF ACK 命令
slave1:ip=127.0.0.1,port=56789,status=online,offset=985,lag=15
master_repl_offset:1289
在一般情况下,lag 的值应该在 0 秒或者 1 秒之间跳动,如果超过 1 秒,那么说明主从服务器之间的连接出现了故障
8.2、辅助实现 min-slaves 配置选项
Redis 的 min-slaves-to-write 和 min-slaves-max-lag 两个选项都可以防止主服务器在不安全的情况下执行写命令
举个例子,如果我们向主服务器提供以下设置:
min-slaves-to-write 3
min-slaves-max-lag 10
那么在从服务器的数量少于 3 个,或者三个服务器的延迟(lag)值都大于或等于 10 秒时,主服务器将拒绝执行写命令,这里的延迟值就是上面提到的 INFO replication
命令的 lag 值
8.3、检测命令丢失
如果因为网络故障,主服务器传播给从服务器的写命令在半路丢失,那么当从服务器向主服务器发送 REPLCONF ACK
命令时,主服务器将发觉从服务器当前的复制偏移量少于自己的复制偏移量,然后主服务器就会根据从服务器提交的复制偏移量,在复制加压缓冲区里面找到从服务器缺少的数据,并将这些数据重新发送给从服务器
注意:主服务器向从服务器补发缺失数据这一操作的原理和部分重同步的原理非常相似,这两个操作的区别在于,补发确实数据在主从服务器没有断线的情况下执行,而部分重同步操作则在主从服务器断线并重连之后执行
REPLCONF ACK
命令和复制积压区都是 Redis 2.8 版本新增的,在 Redis 2.8 版本以前,即使命令在传播过程中丢失,主服务器和从服务器都不会注意到,主服务器更不会向从服务器补发丢失的数据,所以为了保证复制时主从服务器的数据一致性,最好使用 2.8 或以上版本的 Redis
转载请标明出处,原文地址:https://blog.csdn.net/weixin_41835916 如果觉得本文对您有帮助,请点击顶支持一下,您的支持是我写作最大的动力,谢谢。
五、Redis主从同步相关推荐
- Redis主从同步(复制)
一.概述 在现有企业中80%公司大部分使用的是redis单机服务,在实际的场景当中单一节点的redis容易面临风险. 面临问题 机器故障.我们部署到一台 Redis 服务器,当发生机器故障时,需要迁移 ...
- Redis主从同步异常问题记录
一.背景 2015.7.31 10.36.14.*网段的TOR故障一小时,网络故障恢复后,redis nj多个从主从同步异常: 除slave0外,其他slave的offset均比master大.注:r ...
- 浅析 Redis 主从同步与故障转移原理
我们在生产中使用 Redis,如果只部署一个 Redis 实例,当该实例宕机,到恢复之前都不可用:虽说 Redis 一般都用来做缓存,但不可用给业务系统带来的影响也是不小的,流量大时甚至会导致整个服务 ...
- Docker搭建Redis主从同步详细教程
文章目录 介绍: redis主从同步概念 redis主从同步原理 redis主从同步流程图 搭建redis主从详细步骤: 拉取redis镜像 创建所需文件夹,用于映射容器相应文件路径 运行容器指定挂载 ...
- 【Redis】Redis主从同步中数据同步原理
[Redis]Redis主从同步中数据同步原理 文章目录 [Redis]Redis主从同步中数据同步原理 1. 全量同步 1.1 判断是否第一次数据同步 2. 增量同步 3. 优化Redis主从集群 ...
- 六、redis主从同步
参考Redis 的主从同步,及两种高可用方式 010.Redis 主从架构搭建及原理详解 一.介绍 1.简介 redis的主从就是多台redis的数据保持一致.redis主服务器可写入和读取,从服务器 ...
- Redis主从同步模式(replication)
主从同步模式(replication) 主从同步是指以一个节点为基准节点,将数据同步给从节点,使得主从节点的数据保持一致,主节点一般也称为Master,从节点Slave,一个Master节点可以有多个 ...
- 【图解】redis主从同步流程——全量同步、部分同步、命令传播
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.全量同步 二.部分同步 三.命令传播 总结 前言 本文主要介绍Redis高可用下的主从同步问题,包括全量同步.部分 ...
- redis 主从同步到分布式集群
Redis 集群是一个提供在多个Redis节点间共享数据的程序集 通过集群的配置可以解决:机器故障.容量瓶颈.QPS瓶颈等 主从同步 redis主从结构有一主多从和级联结构 一主多从:master将数 ...
最新文章
- RDKit | 化合物描述符向量化及部分结构检索
- MongoDB整理笔记の管理Replica Sets
- centos安装 ping 命令 ( yum provides )
- python源代码最多的学习网站_史上最全Python学习资料大合集分享
- WCF 第十二章 对等网
- 【云炬大学生创业基础笔记】第1章第2节测试
- LabVIEW2018安装教程
- (转)区间合并pushup函数模板
- [Swift]LeetCode482. 密钥格式化 | License Key Formatting
- (转)一台服务器安装两个tomcat6 服务的解决方案
- mysql 数据库链路_MySQL数据库使用(二):配置、连接远端数据库
- 线性分类模型python_python SVM 线性分类模型的实现
- 数值分析(第五版) 第二章知识点总结
- plsa的java实现_java在注解中绑定方法参数的解决方案
- 转会咯,从广州转北京咯!
- 十、基于FPGA的PCIE协议介绍(一)
- SPI协议通信时序详解
- 【读书笔记】面试为什么总考算法_如何避开算法面试
- 液晶屏LED背光板可以分为几类?
- 目标检测制作自己的VOC2007数据集