七:哨兵机制——实现不间断服务
原文:《07丨哨兵机制:主库挂了,如何不间断服务?》
当主库挂了之后,写服务会中断、从库无法进行数据同步。我们需要运行一个新的主库,比如说把一个从库切换为主库,这就涉及到三个问题:
- 主库真的挂了吗?
- 该选择哪个从库作为主库?
- 怎么把新主库的相关信息通知给从库和客户端?
要解决这三个问题,就需要用到哨兵机制。哨兵其实就是一个运行在特殊状态下的Redis进程,只不过不执行读写请求操作。
哨兵机制的流程:
- **监控:**哨兵会在运行过程中,周期性地向所有主从库发送PING命令,判断它们是否在正常运行,没有响应的判为“下线状态”,在该步主要是为了监控主库是否为下线状态;
- **选主:**如果主库没有响应,哨兵就要从很多从库里面按照一定的规则选择一个从库,把它作为新的主库;
- **通知:**哨兵把新主库的连接信息发送给所有从库和客户端,让它们执行replica命令,建立新的主从关系。
1. 监控:判断主库是否下线
哨兵对主库的下线判断分为两种:主观下线和客观下线。
对于从库来说,只要一个哨兵认为其“主观下线”就算是下线了;而对于主库,当一个哨兵认为其“主观下线”时,系统并不会真的把其当作下线,因为可能会因为网络等原因造成该哨兵误判,而主从切换又比较浪费资源,所以需要哨兵集群(下一节讲),当超过quorum数(配置)的哨兵认为主库“主观下线”了,这时候才算主库真的下线了,是为“客观下线”。
当认定主库“客观下线”,哨兵机制就开始进行第二步,选主。
2. 选主
哨兵集群选择一个哨兵进行选主(见下一节),选主的过程为**“筛选+打分”**,在多个从库中,先按照一定的筛选规则,把不符合条件的从库去掉,然后再按照一定的打分规则,选择分最高的从库作为主库。
- **筛选:检查从库的当前运行状态和之前的网络连接状态。如何判断之前的网络连接状态呢?使用配置项down-after-milliseconds * 10,其中down-after-milliseconds(注意,每个哨兵的配置都要一致)**是我们认定的主从库断连的最大连接超时时间,如果在这个毫秒内都没有连接上,就认为断联了。如果断联次数超过10次,则认为之前的网络连接状态不好,排除掉。
- **打分:**有以下三轮打分,如果某一轮可以选出最高分,则直接认定为主库,如果选不出最高分则进行下一轮打分。
- **从库优先级高的得分高:**从库的优先级是我们自己提前配置的;
- **和旧主库同步程度最接近的从库得分高:**把每个从库的slave_repl_offset和主库的master_repl_offset比较,最接近的分最高;
- ID号小的从库得分高。
至此,便可选出新主库。
3. 通知
不涉及逻辑操作,只是哨兵通知其它所有从库和客户端,让他们和新的主库建立主从关系/连接即可。
八:哨兵集群——实现哨兵机制
原文:《08丨哨兵集群:哨兵挂了,主从库还能切换吗?》
如果有哨兵实例在运行时发生了故障,那么主从库还能正常切换吗?
在配置哨兵的时候,只需要设置主库的ip和端口,而不用设置其它哨兵的信息,那么又是怎么组成哨兵集群的呢?
1. 基于pub/sub机制的哨兵集群组成
- 哨兵和哨兵:哨兵实例之间的相互发现,要归功于Redis提供的pub/sub机制,也就是发布/订阅机制。每个节点都可以通过Redis进行消息的发布和订阅,为了区分不同应用的消息,Redis会以频道的形式对这些消息进行管理。每一个哨兵在和主库建立连接之后,就可以在“_ _sentinel _ _:hello”频道上发布自己的连接信息(IP和端口),同时也会订阅这个频道,获取到其它哨兵发布的连接信息,通过这种方法就可以建立起哨兵集群。
- 哨兵和从库:哨兵向主库发送INFO命令,主库收到后就会把从库列表(包含所有从库的连接信息)发送给哨兵,哨兵就可以和每个从库建立连接,进行监听。
- 哨兵和客户端:完成主从切换后,需要把新主库信息告诉给客户端,同时客户端可能也想要了解哨兵的运行状态,比如主从切换进行到哪一步了。这一功能仍然是基于pub/sub机制,只不过是基于哨兵自身的pub/sub机制(每个哨兵本质上也是一个Redis实例),客户端可以从哨兵订阅消息。哨兵提供的消息订阅频道很多,包含了主从切换过程中的不同关键事件,如下图所示为几个关键事件。客户端读取哨兵的配置信息之后,可以获取到哨兵的ip和端口,进行连接,然后订阅想要监听的频道(如SUBSCRIBE +odown监听主库客观下线事件),就可以获取自己想要的信息。
2. 由哪个哨兵执行主从切换?
这个过程类似于对主库进行“客观下线”的判断,也是需要投票决定。当认定主库“客观下线以后”,一个或多个哨兵会给自己投一票,想让自己成为Leader(进行选主操作的哨兵),同时会给其它所有哨兵发送消息,希望他们给自己投票,当某个哨兵获得的票数超过半数(配置奇数个哨兵)且大于配置中的quorum值时,就会当选成为Leader,而如果没有满足条件,哨兵集群就会等待一定时间(避免网络问题影响哨兵选举),然后再次选举。