欢迎光临
我们一直在努力

Redis - 哨兵集群:哨兵挂了,主从库还能切换吗

文章目录

  • 哨兵集群的组建方式
  • 判定主库下线的投票机制
  • 谁来执行故障转移:Leader 选举
  • 故障转移的完整流程
  • 客户端怎么感知切换
  • 哨兵集群的部署建议
  • 哨兵的局限

在这里插入图片描述

单个哨兵监控 Redis 主从架构,本身就是单点。哨兵挂了,主库故障就没人发现、没人切换。所以生产环境必须部署哨兵集群——多个哨兵实例协同工作,任何一个挂了都不影响整体的监控和故障转移能力。

哨兵集群的组建方式

在这里插入图片描述

哨兵实例之间不需要手动配置彼此的地址。它们通过 Redis 的 Pub/Sub 机制自动发现对方。

具体过程:每个哨兵都会向它监控的主库的 __sentinel__:hello 频道发布自己的 IP、端口和运行 ID。同时,每个哨兵也订阅这个频道。这样一来,所有监控同一组主从的哨兵就能互相感知到彼此的存在。

这个设计很巧妙:哨兵的发现依赖于被监控的 Redis 实例本身。只要哨兵们都配置了同一个主库地址,它们就能自动组网。

哨兵还能自动发现从库。它通过向主库发送 INFO 命令,获取所有从库的地址列表,然后逐一建立连接并监控。

在这里插入图片描述

判定主库下线的投票机制

单个哨兵 ping 不通主库,只能算"主观下线"(Subjectively Down,简称 sdown)。网络抖动、哨兵自身负载高都可能导致误判。

在这里插入图片描述

要确认主库真的挂了,需要多个哨兵达成共识——这就是"客观下线"(Objectively Down,简称 odown)。当一个哨兵判定主库 sdown 后,它会询问其他哨兵:"你那边也 ping 不通吗?"如果收到的"同意下线"票数达到配置的 quorum 值,就判定为客观下线。

sentinel monitor mymaster 192.168.1.10 6379 2

最后那个 2 就是 quorum。意思是至少 2 个哨兵都认为主库挂了,才触发故障转移。

谁来执行故障转移:Leader 选举

客观下线只是"判定",接下来要有一个哨兵站出来执行切换操作。这个角色叫 Leader,通过类似 Raft 的选举产生。

在这里插入图片描述

选举规则:

  • 判定 odown 的那个哨兵率先发起投票,请求其他哨兵投票给自己。
  • 每个哨兵在一个 epoch 内只能投一票,先到先得。
  • 拿到多数派(超过哨兵总数一半)同意票的哨兵成为 Leader。
  • Leader 负责执行整个故障转移流程。
  • 注意一个关键区别:quorum 决定"是否下线",多数派决定"谁来切换"。

    举个例子:5 个哨兵,quorum=2。只要 2 个哨兵认为主库挂了就判定 odown,但执行切换需要拿到至少 3 票(5/2+1)。如果此时有 3 个哨兵挂了,虽然能判定下线(剩下 2 个够 quorum),但选不出 Leader(2 < 3),切换就无法执行。

    所以哨兵集群的数量建议是奇数(3 或 5),且要保证大多数存活。

    故障转移的完整流程

    Leader 选出后,执行以下步骤:

  • 从所有从库中选一个新主库。选择标准按优先级排序:

    • 过滤掉网络不稳定的(断连次数超阈值)
    • 优先级高的优先(replica-priority 配置)
    • 复制偏移量大的优先(数据最新)
    • runID 最小的优先(兜底)
  • 向选中的从库发送 SLAVEOF NO ONE,让它升级为主库。

  • 向其他从库发送 SLAVEOF <新主库>,让它们切换复制源。

  • 把旧主库标记为从库。如果旧主库后来恢复了,哨兵会让它以从库身份加入。

  • 客户端怎么感知切换

    哨兵切换完主库后,客户端还连着旧地址怎么办?

    哨兵提供了通知机制。客户端可以订阅哨兵的特定频道(如 +switch-master),收到切换通知后重新连接新主库。主流的 Redis 客户端库(Jedis、Lettuce、redis-py)都内置了哨兵模式的支持,会自动处理这个过程。

    客户端连接哨兵的配置方式:

    from redis.sentinel import Sentinel

    sentinel = Sentinel([
    ('sentinel-1', 26379),
    ('sentinel-2', 26379),
    ('sentinel-3', 26379)
    ], socket_timeout=0.1)

    master = sentinel.master_for('mymaster', socket_timeout=0.1)
    slave = sentinel.slave_for('mymaster', socket_timeout=0.1)

    客户端先问哨兵"当前主库是谁",拿到地址后再直连 Redis。


    哨兵集群的部署建议

    在这里插入图片描述

  • 至少部署 3 个哨兵,分布在不同机器甚至不同机房,避免网络分区时全军覆没。
  • quorum 设为多数派:3 个哨兵设 2,5 个哨兵设 3。
  • 哨兵不要和 Redis 实例部署在同一台机器,否则机器挂了两个一起丢。
  • 哨兵本身不需要持久化,它的状态信息会写到配置文件里,重启后能恢复。
  • 监控哨兵本身的健康状态,哨兵挂了不会有人自动修复它。
  • 哨兵的局限

    哨兵解决了主从架构的自动故障转移问题,但它有几个天然限制:

    • 写能力无法扩展:所有写流量都打到一个主库,主库的内存和 CPU 就是上限。
    • 存储容量受限于单机内存:主从只是副本,不是分片。
    • 切换期间有短暂不可用:从发现故障到完成切换,通常需要 10-30 秒。

    当单机内存不够用、或者写入量超过单机承载能力时,就需要切片集群了。哨兵负责的是"高可用",切片集群负责的是"可扩展",两者解决的是不同层面的问题。

    在这里插入图片描述

    赞(0)
    未经允许不得转载:171主机测评 » Redis - 哨兵集群:哨兵挂了,主从库还能切换吗
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址