哨兵

高可用主要来自两方面:
- 数据主从节点之间会有同步,如果主节点没了,从节点还有数据
- 有哨兵节点进行监控,选主。主节点崩了,重新选一个,继续向外提供服务
为什么要有哨兵?
在Redis的主从架构中,读写是分离的,如果主没了,那就没人来处理写命令了,也没法给同节点同步数据了
这时如果要恢复服务的话,需要人工介入,选择一个「从节点」切换为「主节点」,然后让其他从节点指向新
的主节点,同时还需要通知上游那些连接 Redis 主节点的客户端,将其配置中的主节点 IP 地址更新为「新主
节点」的 IP 地址。
redis 2.8后就推出了一种新模式,即Sentinel,干的事情就是监控主节点是否宕机
以及主节点宕机选主,然后把数据同步给从节点和客户端
有了哨兵后,客户端就可以 和sentinel通信,然后获取主节点信息

哨兵如何工作?
哨兵其实是运行在特殊环境下的一个Redis进程,所以它是一个节点,但实际落地哨兵也是有多个的。
主要负责三件事:监控,选主,通知
如何判断主节点是否真故障?
哨兵每隔一秒给主从节点发心跳包,主从节点在规定时间内回了那就是正常的。
如果没有哨兵就会将它们标记为「主观下线」。这个「规定的时间」是配置项 down-after-millisecon
参数设定的,单位是毫秒。
下线分主观和客观,主观就是唯心的即实际不一定的,从节点只会被标记为客观
主节点可能会因为请求压力大,导致网络阻塞从而回消息慢了点,不是真下线
然后为了避免这种情况,即增强纠错机制,哨兵也是议会制的,即多个哨兵都认为它宕机了它才宕机
增加容错度
具体是怎么判定主节点为「客观下线」的呢?
当有一个哨兵认为主节点下线后,就会通知其他哨兵,根据自身和主节点的网络情况,做出攒成和反对的投
票。
当这个哨兵的赞同票数达到哨兵配置文件中的 quorum 配置项设定的值后,这时主节点就会被该哨兵标记为
「客观下线」。
PS:quorum 的值一般设置为哨兵个数的二分之一加 1,例如 3 个哨兵就设置 2。
判断完后就会从从节点里选一个出来作为主节点
哪个哨兵来进行选主呢?
哨兵投票投出来的。一般会有候选者。
哪个哨兵节点判断主节点为「客观下线」,这个哨兵节点就是候选者,所谓的候选者就是想
当 Leader 的哨兵。
每个哨兵只有一次投票机会,如果用完后就不能参与投票了,可以投给自己或投给别人,但是只有候选者才能
把票投给自己。
那么在投票过程中,任何一个「候选者」,要满足两个条件:
第一,拿到半数以上的赞成票;
第二,拿到的票数同时还需要大于等于哨兵配置文件中的 quorum 值。
举个例子,假设哨兵节点有 3 个,quorum 设置为 2,那么任何一个想成为 Leader 的哨兵只要拿到 2 张赞成票,就可以选举成功了。如果没有满足条件,就需要重新进行选举。
如果某个时间点,刚好有两个哨兵节点判断到主节点为客观下线,那这时不就有两个候选者了?这时该如何决定谁是 Leader 呢?
简单来说,谁先发现有个节点故障了,谁就是候选者,如果只有一个候选者,一般就是它成为Leader,如果
同时有多个候选者,看其它投票者先给谁投票,谁就是Leader
主从故障转移的过程是怎样的?
- 从已下线的主节点下的从节点里挑一个出来
- 让从节点修改copy目标
- 将新主节点的ip地址和信息,通过pub/sub通知到客户端里去
- 继续监视已下线的主节点,如果它复活了,那就将它设置为新主节点的从节点
步骤一:挑选过程
先过滤掉网络不健康的从节点,然后三轮考察,一是优先级,二是复制进度,三是ID号
前两个都是谁大谁win,id号是谁小谁win
winer出来后,然后向这个「从节点」发送 SLAVEOF no one 命令,将这个「从节点」转换为「主节点」
步骤二:让从节点更改
哨兵向原从节点发送 slaveof 命令
步骤三:通知客户的主节点已更换
经过前面一系列的操作后,哨兵集群终于完成主从切换的工作,那么新主节点的信息要如何通知给客户端
呢?
这主要通过 Redis 的发布者/订阅者机制来实现的。每个哨兵节点提供发布者/订阅者机制,客户端可以从哨兵订阅消息。
哨兵提供的消息订阅频道有很多,不同频道包含了主从节点切换过程中的不同关键事件,几个常见的事件如下:

客户端和哨兵建立连接后,客户端会订阅哨兵提供的频道。主从切换完成后,哨兵就会向 +switch-master 频道发布新主节点的 IP 地址和端口的消息,这个时候客户端就可以收到这条信息,然后用这里面的新主节点的 IP 地址和端口进行通信了。
通过发布者/订阅者机制机制,有了这些事件通知,客户端不仅可以在主从切换后得到新主节点的连接信息,还可以监控到主从节点切换过程中发生的各个重要事件。这样,客户端就可以知道主从切换进行到哪一步了,有助于了解切换进度
步骤四:将旧主节点变为从节点
故障转移操作最后要做的是,继续监视旧主节点,当旧主节点重新上线时,哨兵集群就会向它发送 SLAVEOF 命令,让它成为新主节点的从节点
哨兵集群如何组成?
在配置哨兵信息的时候,只需要设置这几个参数,主节点名字,主节点的IP地址和端口号以及 qunorum值
不需要填其他哨兵的信息,哨兵节点之间是通过订阅发现机制来互相发现的
在主从集群中,主节点上有一个名为 sentinel:hello的频道,不同哨兵就是通过它来互相发现的,
实现互相通信的
哨兵主节点只要发布信息到到这个频道上,哨兵b,c订阅了这个频道,就可以互相通信了,集群就这样形成了
哨兵如何知道从节点信息?
主节点知道所有从节点的信息,所以从节点每秒10s就向主节点发INFO请求获取所有从节点的信息