Redis 使用哨兵服务保证服务的高可用。

哨兵的作用

  • 监控:向主、从库发送心跳,确定主、从库是否下线
  • 选主:哨兵判断主库已下线时,从从库中筛选出一个作为新的主库
  • 通知:选主后,将主库信息通知给从库和 client

    哨兵集群

    哨兵在向主库发送心跳时,可能会由于网络波动等原因照成哨兵误判主库下线。为防止哨兵误判,引入哨兵集群。

  • 监控:由集群内的各个哨兵判断主从库是否 “主观下线”

  • 选主:有哨兵 “主观” 判断主库已下线时发起投票,投票通过后主库为 “客观下线”状态,由哨兵 Leader 重新选主
  • 通知:选主后,由哨兵 Leader 将主库信息通知给从库和 client

    如何判断主库 “客观下线”❓

  1. 集群内的各个哨兵分别向主库发送心跳
  2. 有哨兵 “主观” 判断主库已下线时发起投票
  3. 投赞成票的哨兵数量 >= 哨兵配置文件中的 quorum 值,标识主库为 “客观下线” 状态,否则投票作废

    如何成为 Leader❓

  4. 哨兵 A “主观判断” 主库下线后,发起主库下线投票

  5. 投票通过后,哨兵 A 发起 Leader 竞选,赞成票数+1
  6. 其它哨兵收到竞选信息后投票
    1. 当前哨兵也发起了竞选时,返回反对票
    2. 当前哨兵已经投过赞成票时,返回反对票
    3. 当前哨兵未发起竞选且未投过赞成票时,返回赞成票
  7. 赞成票数 > 哨兵总数/2 && 赞成票数 >= 哨兵配置文件中的 quorum 值时,哨兵当选 Leader

ps:允许同时存在多个哨兵发起竞选的情况,如:
image.png

如何选主❓

主库被 “客观下线” 后,由哨兵 Leader 重新选主。

  1. 筛选掉网络不稳定(主从断连次数超过设置的阈值)的实例
  2. 筛选出优先级最高的实例
  3. 存在多个优先级最高且相等的实例时,筛选出 offset 值最大(即数据最新)的实例
  4. 依然存在多个实例时,选出 id 最小的实例作为新的主库

    哨兵是如何发现其它哨兵的❓

    哨兵与主库建立连接后会将自身信息发布到 __sentinel__:hello 频道内,其它哨兵会订阅这个频道,在收到消息后与之建立连接。
    image.png

    哨兵是如何发现从库的❓

    哨兵与主库建立连接后,通过 INFO 命令获取从库信息。
    image.png

    哨兵是如何通知 Client 的❓

    客户端通过哨兵配置文件与哨兵建立网络连接后订阅不同的频道获取不同的消息,亦可订阅所有频道
    主要频道如下:
    image.png