- 心跳检测
- 检测主从服务器的网络连接状态
- 辅助实现min-slaves配置选项
- 拓展min-slaves
- 检测命令丢失
心跳检测
前面说过主从同步的最后一个步骤就是传播命令,现在问题来了,主服务器怎么去及时确定从服务器依然在连接呢?Redis使用了心跳检测去解决这个问题
什么是心跳检测呢?
在命令传播阶段,从服务器默认会以每秒一次的频率,向主服务器发送下面命令
replconf ack <replication_offset>
其中replication_offset是从服务器自身维护的一个复制偏移量(前面就提到过,新版复制功能的主从服务器都会维护自己的一个复制偏移量)
问题来了,如果是为了单纯检测从服务器是否在连接,为什么不使用更加简单的Ping命令
发送REPLCONF ACK命令其实有三个作用
- 检测主从服务器的网络连接状态
- 辅助实现min-slaves选项
- 检测命令丢失(防止网络传输的丢包)
检测主从服务器的网络连接状态
主从服务器可以通过发送和接收REPLCONF ACK命令来检测两者之间的网络连接是否正常,如果主服务器超过1秒没有接收到从服务器发来的REPLCONF ACK命令,那么就证明主从服务器的网络连接状态出现了问题。。。
辅助实现min-slaves配置选项
Redis的min-slaves-to-write和min-slaves-max-lag两个选项是可以防止主服务器在不安全的情况下执行写命令,这两个选项在配置文件中对应为下图
min-replicas-to-write配置是用来限制主服务器的写操作的,当网络健康的从服务器小于min-replicas-to-write属性,主服务器就会禁止写操作,当出现一个从服务器的延迟高于min-replicas-max-log秒,也会禁止主服务器的写操作。也就是说,只有网络健康的从服务器的数量不小于min-replicas-to-write和所有的从服务器的延迟均低于min-replicas-max-log,主服务器才可以进行写操作,我们回到info replication命令
Info replication可以显示从服务器最后一次发送REPLCONF ACK命令所需要的秒数,通过比对REPLCONF ACK命令执行的秒数,就可以进行判断了。
拓展min-slaves
min-slave这个配置是用来减少主从服务器不一致的状态情况的,虽然不可以保证所有的salves都可以接收到主服务器的新执行的写命令,但可以保证只要有一定数量不健康的salves,主服务器就可以不进行写操作,从而避免了数据丢失,减少了主从服务器状态不一致现象。
检测命令丢失
如果因为网络故障,发生了一些丢包之类的现象,主服务传播给从服务器的写命令是可能会在半路丢失的,当从服务器向主服务器发送REPLCAONF ACK命令时,会带上自己的复制偏移量,主服务器就可以比较自己维护的复制偏移量与从服务器的是否一致,如果不一致(不一致只可能是从服务器的复制偏移量小于主服务器),主服务器就会进行类似部分重同步的操作,就是会在复制积压缓冲区里面找到从服务器丢失的数据,并且将这些数据重新发送给服务器。
当然这仍然有缺点,假如这一秒内,发送了很多次写命令,其中丢失了前面的一部分,但后面的一部分成功了,那么从服务器那边的复制偏移量并不会停留在丢失前面的一部分的偏移量那里,这样仍然会导致数据丢失。
注意
对于检测命令丢失,并不是执行部分重同步操作,这只是类似于部分重同步操作,部分重同步操作是针对于从服务器断开连接的,而检测命令丢失,从服务器是没有发生断线情况的。