如果要在网络分割出现的情况下仍然保持一致性,那么应该使用 min-slaves-to-write 选项,让主服务器在连接的从实例少于给定数量时停止执行写操作,与此同时,应该在每个运行 Redis 主服务器或从服务器的机器上运行 Redis Sentinel 进程。
Sentinel 状态的持久化
Sentinel 的状态会被持久化在 Sentinel 配置文件里面。
每当 Sentinel 接收到一个新的配置,或者当领头 Sentinel 为主服务器创建一个新的配置时,这个配置会与配置纪元一起被保存到磁盘里面。
这意味着停止和重启 Sentinel 进程都是安全的。
Sentinel 在非故障迁移的情况下对实例进行重新配置
即使没有自动故障迁移操作在进行,Sentinel 总会尝试将当前的配置设置到被监视的实例上面。特别是:
根据当前的配置,如果一个从服务器被宣告为主服务器,那么它会代替原有的主服务器,成为新的主服务器,并且成为原有主服务器的所有从服务器的复制对象。那些连接了错误主服务器的从服务器会被重新配置,使得这些从服务器会去复制正确的主服务器。不过,在以上这些条件满足之后,Sentinel 在对实例进行重新配置之前仍然会等待一段足够长的时间,确保可以接收到其他 Sentinel 发来的配置更新,从而避免自身因为保存了过期的配置而对实例进行了不必要的重新配置。
TILT 模式
Redis Sentinel 严重依赖计算机的时间功能:比如说,为了判断一个实例是否可用,Sentinel 会记录这个实例最后一次相应 PING 命令的时间,并将这个时间和当前时间进行对比,从而知道这个实例有多长时间没有和 Sentinel 进行任何成功通讯。
不过,一旦计算机的时间功能出现故障,或者计算机非常忙碌,又或者进程因为某些原因而被阻塞时,Sentinel 可能也会跟着出现故障。
TILT 模式是一种特殊的保护模式:当 Sentinel 发现系统有些不对劲时,Sentinel 就会进入 TILT 模式。
因为 Sentinel 的时间中断器默认每秒执行 10 次,所以我们预期时间中断器的两次执行之间的间隔为 100 毫秒左右。Sentinel 的做法是,记录上一次时间中断器执行时的时间,并将它和这一次时间中断器执行的时间进行对比:
如果两次调用时间之间的差距为负值,或者非常大(超过 2 秒钟),那么 Sentinel 进入 TILT 模式。如果 Sentinel 已经进入 TILT 模式,那么 Sentinel 延迟退出 TILT 模式的时间。当 Sentinel 进入 TILT 模式时,它仍然会继续监视所有目标,但是:
它不再执行任何操作,比如故障转移。当有实例向这个 Sentinel 发送 SENTINEL is-master-down-by-addr 命令时,Sentinel 返回负值:因为这个 Sentinel 所进行的下线判断已经不再准确。如果 TILT 可以正常维持 30 秒钟,那么 Sentinel 退出 TILT 模式。
处理 -BUSY 状态
该功能尚未实现
当 Lua 脚本的运行时间超过指定时限时,Redis 就会返回 -BUSY 错误。
当出现这种情况时,Sentinel 在尝试执行故障转移操作之前,会先向服务器发送一个 SCRIPT KILL 命令,如果服务器正在执行的是一个只读脚本的话,那么这个脚本就会被杀死,服务器就会回到正常状态。
Sentinel 的客户端实现
关于 Sentinel 客户端的实现信息可以参考 Sentinel 客户端指引手册 。