bigywater.tech
Redis · 89

Sentinel 自动故障转移

Sentinel 的自动故障转移由一串事件组成,每个都有名字(+sdown、+odown、+elected-leader、+promoted-slave、+switch-master……)。这篇订阅 sentinel 的事件流,把一次真实 kill -9 之后的每一个事件和毫秒数都列出来,再从写客户端的角度量不可用时长。

5.3 s
kill -9 主库到 +failover-end 的总时间(down-after-milliseconds = 3000)
约 4.3 s
写客户端(经 sentinel 找主库)不可用的时长
10.2 s
旧主库重启后被 sentinel 改成从库并 link up 所用的时间

完整的事件流

时间相对 kill -9;s0/s1/s2 是三个 sentinel
实测 · 本机执行输出
+  3046 ms  s1  +sdown                               master mymaster 127.0.0.1 7740
+  3094 ms  s2  +sdown                               master mymaster 127.0.0.1 7740
+  3098 ms  s0  +sdown                               master mymaster 127.0.0.1 7740
+  3177 ms  s0  +odown                               master mymaster 127.0.0.1 7740 #quorum 3/2
+  3177 ms  s0  +new-epoch                           1
+  3177 ms  s0  +try-failover                        master mymaster 127.0.0.1 7740
+  3177 ms  s0  +vote-for-leader                     4570effe484f7513910e9464e58a0cad40caeec2 1
+  3179 ms  s2  +odown                               master mymaster 127.0.0.1 7740 #quorum 2/2
+  3179 ms  s2  +new-epoch                           1
+  3179 ms  s2  +try-failover                        master mymaster 127.0.0.1 7740
+  3179 ms  s2  +vote-for-leader                     59ffdbdd56a9a3d80a8028ef42b76862d0a29d8d 1
+  3185 ms  s1  +new-epoch                           1
+  3185 ms  s1  +vote-for-leader                     4570effe484f7513910e9464e58a0cad40caeec2 1
+  3256 ms  s0  +elected-leader                      master mymaster 127.0.0.1 7740
+  3256 ms  s0  +failover-state-select-slave         master mymaster 127.0.0.1 7740
+  3318 ms  s0  +selected-slave                      slave 127.0.0.1:7741 127.0.0.1 7741 @ mymaster 127.0.0.1 7740
+  3318 ms  s0  +failover-state-send-slaveof-noone   slave 127.0.0.1:7741 127.0.0.1 7741 @ mymaster 127.0.0.1 7740
+  3378 ms  s0  +failover-state-wait-promotion       slave 127.0.0.1:7741 127.0.0.1 7741 @ mymaster 127.0.0.1 7740
+  4178 ms  s1  +odown                               master mymaster 127.0.0.1 7740 #quorum 3/2
+  4179 ms  s1  -role-change                         slave 127.0.0.1:7741 127.0.0.1 7741 @ mymaster 127.0.0.1 7740 ne
+  4200 ms  s0  -role-change                         slave 127.0.0.1:7741 127.0.0.1 7741 @ mymaster 127.0.0.1 7740 ne
+  4200 ms  s0  +promoted-slave                      slave 127.0.0.1:7741 127.0.0.1 7741 @ mymaster 127.0.0.1 7740
+  4200 ms  s0  +failover-state-reconf-slaves        master mymaster 127.0.0.1 7740
+  4247 ms  s0  +slave-reconf-sent                   slave 127.0.0.1:7742 127.0.0.1 7742 @ mymaster 127.0.0.1 7740
+  4254 ms  s1  +config-update-from                  sentinel 4570effe484f7513910e9464e58a0cad40caeec2 127.0.0.1 7760
+  4254 ms  s1  +switch-master                       mymaster 127.0.0.1 7740 127.0.0.1 7741
+  4254 ms  s1  +slave                               slave 127.0.0.1:7742 127.0.0.1 7742 @ mymaster 127.0.0.1 7741
+  4254 ms  s1  +slave                               slave 127.0.0.1:7740 127.0.0.1 7740 @ mymaster 127.0.0.1 7741
+  4254 ms  s2  +config-update-from                  sentinel 4570effe484f7513910e9464e58a0cad40caeec2 127.0.0.1 7760
+  4254 ms  s2  +switch-master                       mymaster 127.0.0.1 7740 127.0.0.1 7741
+  4254 ms  s2  +slave                               slave 127.0.0.1:7742 127.0.0.1 7742 @ mymaster 127.0.0.1 7741
+  4254 ms  s2  +slave                               slave 127.0.0.1:7740 127.0.0.1 7740 @ mymaster 127.0.0.1 7741
+  5221 ms  s0  +slave-reconf-inprog                 slave 127.0.0.1:7742 127.0.0.1 7742 @ mymaster 127.0.0.1 7740
+  5221 ms  s0  +slave-reconf-done                   slave 127.0.0.1:7742 127.0.0.1 7742 @ mymaster 127.0.0.1 7740
+  5280 ms  s0  -odown                               master mymaster 127.0.0.1 7740
+  5280 ms  s0  +failover-end                        master mymaster 127.0.0.1 7740
+  5280 ms  s0  +switch-master                       mymaster 127.0.0.1 7740 127.0.0.1 7741
+  5280 ms  s0  +slave                               slave 127.0.0.1:7742 127.0.0.1 7742 @ mymaster 127.0.0.1 7741
+  5280 ms  s0  +slave                               slave 127.0.0.1:7740 127.0.0.1 7740 @ mymaster 127.0.0.1 7741

阶段:检测(+sdown/+odown)→ 选领导者(+try-failover/+vote-for-leader/+elected-leader)→ 选从库(+selected-slave)→ 发 SLAVEOF NO ONE 并等升主(+promoted-slave)→ 广播新配置(+config-update-from/+switch-master)→ 其它从库改指新主库(+slave-reconf-*)→ 结束(+failover-end)。

客户端看到的

实测 · 本机执行输出
   新主库地址(sentinel 眼中): ('127.0.0.1', 7741)

一个每 20 ms 经 sentinel 查主库地址再写的客户端:主库被杀 22 ms 后第一次失败,直到新主库可写才恢复。整个不可用窗口里最长的一段是检测(down-after-milliseconds),真正的「选举 + 提升」只占约一秒。

复制拓扑

实测 · 本机执行输出
  7741: role=master
  7742: role=slave master_port=7741 link=up

最终 7741 是主库,7742 是它的从库并且 link up。

旧主库回来

实测 · 本机执行输出
  旧主库 7740 重启后 10188 ms:role = slave,master_port = 7741

旧主库重启后,sentinel 把它配置成新主库的从库(重启后一直处于「主库」身份,直到 sentinel 发现并降级);这里用了 10.2 s。这期间旧主库如果被写入,数据会在降级时丢弃(第 91、93 篇)。

分步演示:自动故障转移

Sentinel 自动故障转移
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / Redis 8.10.2 独立实例(本机回环端口,save 关闭),redis-cli 风格输出由自写的 RESP 客户端打印;计时用 time.perf_counter,数字每次运行会有小幅抖动。1 主 2 从 + 3 个 sentinel,quorum 2,down-after 3000,parallel-syncs 1;事件来自订阅 * ;写客户端每 20 ms 经 sentinel 找主库
    • 没有验证:从库优先级与复制偏移量对选择的影响、parallel-syncs 更大时的拓扑收敛、旧主库降级由哪一步触发以及耗时 10 秒的来源、跨机器网络
    京ICP备2026067502号-1京公网安备11010502063487号