Redis中的Failover机制

在Redis7中,实现了主动的Failover机制,以支持用户能主动的进行主从切换。PR参考:implement FAILOVER command by allenfarris · Pull Request #8315 · redis/redis

Failover命令

1
FAILOVER [ABORT] [TO <HOST> <IP>] [FORCE] [TIMEOUT <timeout>] 

命令包括几种操作:

  • ABORT:直接中断failover操作
  • TO:明确failover的实例
  • FORCE:强制failover操作
  • TIMEOUT:制定failover的超时时间,避免长时间的等待。

从最简单的failover操作来看,当前的操作必须在Master实例上运行,同时可以指定或者随机一个replica进行failover操作。

在设置完failover后,整个Master实例会进入一个 FAILOVER_WAIT_FOR_SYNC 的状态,同时暂停整个实例的变更,操作等同于CLIENT PAUSE

而在整个failover中,存在3类状态:

  • NO_FAILOVER:无状态
  • FAILOVER_WAIT_FOR_SYNC:等待同步
  • FAILOVER_IN_PROGRESS:进行中

进入 FAILOVER_WAIT_FOR_SYNC 状态后,实例会定期检查当前的failover情况。若超时,则确定是否存在force标识,存在则强制进行切主操作。否则则中断 failover 进度。

正常流程,则会选择一个 replica 作为目标实例进行 failover。 目标实例的标准若非自行选择,则要求 offset 必须拉齐,保证数据完整性。

等待 replica 数据同步完成后,便进入 FAILOVER_IN_PROGRESS 进行实例切换。

实例切换

在 FAILOVER_IN_PROGRESS 过程中,需要关注什么下会转换为 NO_FAILOVER 状态。在建立关系后,旧 Master 收到新 Master 的 +CONTINUE+FULLRESYNC 信息,则认为关系已经建立,可以清理掉 failover 状态。

而在建立连接时,旧 Master 会发送 PSYNC <replid> <reploff> FAILOVER 命令给新 Master。此操作主要是告知新 Master 需要从原有的 Replica 状态转换为 Master。

数据保证

在整个 Failover 过程中,旧 Master 会进行停写,同时,不再对所有 Replica 进行数据传输(包括PING操作),以此,实际的数据不会变化,这样对整个复制链的数据迁移是友好的。故,理论上在 主从切换时,大概率是增量同步,且数据不会丢失。