1.哨兵模式

哨兵在redis集群架构中是一个非常重要的组件**,具有监控、通知、故障转移的功能。**

  • 哨兵也是一台 Redis 服务器,只是不对外提供任何服务。配置哨兵时配置为单数,哨兵使用的配置文件是 sentinel.conf
  • 哨兵集群至少要 3 个节点,来确保自己的健壮性。
  • redis主从 + sentinel的架构,是不会保证数据的零丢失的,它是为了保证redis集群的高可用。

2.哨兵的作用

  • 监控:监控主节点和从节点是否正常运行;
  • 通知:哨兵检测的服务器出现问题时,会向其他的哨兵发送通知,哨兵之间就相当于一个通信群,每个哨兵发现的问题都会发在这个群里。
  • 自动故障转移:当检测到主节点宕机后,断开与宕机主节点连接的所有从节点,在从节点中选取一个作为主节点,然后将其他的从节点连接到这个最新主节点的上。并且告知客户端最新的服务器地址。

3.哨兵监控工作流程

哨兵有三个定时监控任务完成对各节点的发现和监控

  • 每隔10秒, 每个哨兵 向 master和slave 发送 info命令,
  • 通过向主节点发送info,主节点返回 run_id 与 从节点的信息,当有新的从节点加入时可以马上感知。
  • 每隔2秒, 每个哨兵 , 利用发布订阅的特性
  • 向redis数据节点的 指定频道(sentinel:hello) 发送, 包括自己的host、ip和runid还有对这个master的监控配置。
  • 每个哨兵节点也会订阅该频道,来了解其它哨兵节点的信息及对主节点的判断,
  • 每隔1秒, 每个哨兵会向主节点,从节点及其余哨兵节点发送ping命令,做心跳检测,用于判定是否存活。

4.哨兵工作流程(故障转移原理)

  • 哨兵会一直给主节点发送 publish sentinel:hello,直到哨兵报出 sdown
  • 若某个哨兵检测到主节点挂了,就会在哨兵群里通知。
  • 其余的哨兵接收到指令后,发送 hello 信息,检测主节点是否真的挂了 。
  • 对于一个哨兵认为主节点挂了称之为主观下线,半数哨兵认为主节点挂了称之为客官下线。

一旦被认为主节点客官下线后。哨兵间会投票来竞选出一个代表

  • 每个哨兵-携带携带runid和自己竞选次数,参与竞选。
  • 每个哨兵都可以投票,规则一般可以通过,认为先收到谁的消息投票给谁。
  • 投票截止到任意一个哨兵的票数为总哨兵数的一半以上,这个就是选为哨兵代表。(这也是哨兵需要基数的原因)

代表哨兵会发消息给所有Redis子节点

  • 不在线的淘汰:
  • 响应慢的干掉
  • 与原主节点断开时间最久的干掉
  • 若还剩下多个
  • 根据配置的优先级,(slave 的 priority 设置的越低,优先级越高;)。
  • redis.conf文件中配置的slave-priority进行排序,更低的优先级会被优先
  • 根据偏移量,判断数据的同步性(slave 复制的数据越多优先级越高)
  • 论资排辈 , 还可以使用 run id 小的 创建时间早。

最后 代表哨兵从新的master配置configuration epoch 一个配置的version进行配置传播,选出新的主节点将断开原主节点。

  • 并且其它的从节点连接新的主节点,
  • 原主节点上线后作为从节点连接
  • 发布到哨兵订阅群里,根据版本更新配置

5.优缺点

  • 优点
  • 高可用,在主节点故障时能实现故障的转移
  • 缺点:
  • 无法做到水平拓展,分布式存储
  • 哨兵本身没有实现高可用,哨兵如果宕机,则直接影响使用

6.数据丢失处理

  • 异步复制时,master挂了还没同步到slave
  • 集群脑裂,master短暂对哨兵slave不可用,哨兵选举新master,但老master对客户端可用有新数据写入,恢复通行后老master变为slave新写入数据丢失。

解决方案:
修改redis配置

# 要求至少有1个slave数据复制和同步的延迟不能超过10秒,不然master会拒绝写请求(客户端需要对redis写操作降级)
min-replicas-to-write 1
min-replicas-max-lag 10

最多会丢失10秒的数据,老master拒绝写请求需要客户端做降级处理,如果redis不能写需临时写本地磁盘或者mq等Redis恢复了在慢慢消费。