本文主要学习https://time.geekbang.org/column/article/275337
在 Redis 主从集群中,哨兵机制是实现主从库自动切换的关键机制,它有效地解决了主从复制模式下故障转移的这三个问题。
- 主库真的挂了吗?
- 该选择哪个从库作为主库?
- 怎么把新主库的相关信息通知给从库和客户端呢?
哨兵其实就是一个运行在特殊模式下的 Redis 进程,主从库实例运行的同时,它也在运行。哨兵主要负责的就是三个任务:监控、选主(选择主库)和通知
流程:
1.哨兵运行时,会向主从redis,发送ping,如果没有相应,就判断下线.如果leader下线,会触发选主
2.选出新主库.
3.通知客户端,换老大了; 告诉其他从库,换老大了,去同步新老大的数据.
这里面有几个问题.
1.怎么正确判断leader下线了.
误判一般会发生在集群网络压力较大、网络拥塞,或者是主库本身压力较大的情况下.或者哨兵本身出问题了,我们要做的就是减少误判!
另一个问题,哨兵不能只有一个,这样哨兵就变成单点了.
so,实际上,会有一个哨兵集群. 这里面有两个概念.记不记都行.主观下线/客观下线. 主观线下就是一个哨兵觉得leader挂了,客观下线就是大部分哨兵觉得leader挂了.到处可见的 少数服从多数 原则
具体流程:
第一步,主观判断下线,任何一个哨兵都可以
- 一个哨兵发现leader挂了,发送is-master-down-by-addr命令给其他哨兵
- 其他哨兵收到请求后,判断是否真的挂了,响应Y/N
- 收到票数>quorum配置,就可以判断leader挂了,那么接下来就是谁来执行切换,选择新主库.
第二步,哨兵选主,以此来觉得谁去切换
这个就是一个过半选举机制啦.
2.怎么选择新主库
筛选+打分
筛选阶段:
过滤掉 下线的(哨兵ping不通)/网络不好的, 啥叫网络不好的,就是和leader经常断.
打分:
- 优先级高的 例如1机器内存大,性能好,就可以配置优先级高,通过slave-priority
- 复制进度快的,无话可说
- id小的, 都差不多的话,就随便选一个吧. (zk就是选nodeId大的,看心情吧)
3.哨兵集群间的通信,哨兵和leader的通信,哨兵和follower的通信,哨兵和client的通信
上面的逻辑,我们都把哨兵看成了一个整体.他实际是一个集群.
3.1 哨兵间的通信(pub/sub)
依赖的是订阅(pub/sub)机制.哨兵启动时,会配置redis leader地址,并将自己发布到redis中(__sentinel__:hello).其他哨兵通过订阅,就能知道新进来一个哨兵.
3.2 哨兵和follower的通信(info命令)
哨兵要向leader发送ping, 这个启动会配置leader地址.
那follower呢?怎么获取呢?
向leader发送info命令即可
3.2 哨兵和client的通信(pub/sub 哨兵机器)
如果主从切换了,怎么通知client.我们在公司使用哨兵时,会返回哨兵的地址.也强调要通过哨兵获取leader地址.
哨兵本身也是redis进程,只不过干的活不一样. leader负责读写/follower负责同步以及读/哨兵负责监控选主通知. 所以哨兵所在进程也会提供pub/sub机制. client可以通过订阅,来获取主从切换这些事件.