Raft算法应用——Redis哨兵选举

278 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

在前一篇博客中我们谈到了Paxos算法以及其变种Raft算法(初识强一致性算法--Paxos、Raft - 掘金 (juejin.cn))这篇文章我们探讨一下Raft算法的实际应用——Redis哨兵选举。首先说明Redis哨兵选举并没有完全运用Raft算法,只是运用Raft算法中的子问题Leader的选举

一、哨兵

首先我们来谈一谈哨兵(Sentinel)。哨兵是Redis集群高可用的一种实现,哨兵通过心跳机制监视集群中的主服务器和从服务器,当哨兵监视到集群中的主服务器没有响应心跳时,会先判断该主服务器主观下线,并且通知其他哨兵进行判断,当超过一半的哨兵认为该服务器主观下线该服务器构成客观下线,此时哨兵集群中会选举出一个“头领”哨兵,将主服务器下线,并通过一定的规则拉起从服务器作为集群新的主服务器,并完成新的主从复制。选举“头领”哨兵的过程就运用Raft算法的Leader选举过程。

在讨论选举过程我们先来了解一下哨兵的。哨兵的本质是一个特殊运行状态下的Redis服务器,去掉了数据库功能并维护一些新的信息例如集群中主从服务器地址、端口号等等。在启动哨兵后系统会建立一个结构称为“sentinelState”用以保存服务器中所有与哨兵功能有关的状态。在“sentinelState”中有一个字典表保存着被监视的服务器以及其他哨兵的信息,通过这些信息,哨兵可以通过订阅、连接主从服务器,连接其他哨兵,完成对系统内所有服务器的监视,以及接受其他哨兵传来的信息。“sentinelState”还存在一个计数器“config_epoch”,用于进行故障转移。

二、“头领”选举

当一个主服务器被判断为客观下线的时候,监视该服务器的哨兵就会选举出一个“头领”进行故障转移。

哨兵集群的任何一个哨兵都能成为“头领哨兵”,每个发现服务器下线的哨兵都会向其他哨兵发送命令,要求其他哨兵将自己作为“局部头领”哨兵。设置“局部头领”哨兵的过程是先到先得,当A哨兵接收到了B哨兵的信息后,A哨兵就将B哨兵作为头领哨兵,并且拒绝其他所有哨兵要求设置头部哨兵的信息同时使“config_epoch”加1。并且A哨兵会向B哨兵发送一条信息,里面记录着B哨兵的id,当B哨兵接收到信息后,就知道已经有一台哨兵将自己作为了“头领”哨兵。当集群中有一台哨兵胜出后就称为哨兵集群的“头领”哨兵,完成接下里的故障转移。如果在给定的时间内没有完成“头领”的选举,哨兵将会在一段时间后重新选举,直到选出“头领”哨兵为止。

因为“头领”哨兵需要半数以上其他哨兵的支持,同时由上面的过程可知,在一次选举中,每个哨兵只会设置一次哨兵,因此集群中只会产生一个“头领”哨兵。“config_epoch”实际上就是一个计数器,表示一次选举,在选举的过程中用以校验信息,其他并无特别之处。