这是我参与更文挑战的第 4 天,活动详情查看: 更文挑战
Redis的多级解决方案主要有3种:复制、哨兵和集群,今天我们主要来讲讲哨兵。
什么是Sentinel?它起什么作用?
Sentinel是Redis高可用的解决方案。通过一个或多个Sentinel组成的Sentinel系统去监视主从服务器。当主服务器下线时,自动将某个从服务器升级为主服务器。
Sentinel本质上是一个特殊的Redis服务器。我们可以通过配置或命令去启动它。
redis-sentinel /path/to/sentinel.conf
或者
redis-server /path/to/sentinel.conf --sentinel
sentinel配置文件
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 60000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
sentinel monitor <master-group-name> <ip> <port> <quorum>
为要监视的主节点命名(无须管从节点),quorum个数表示多少个sentinel认为主节点主观下线便认为其客观下线。
内部细节
启动一个Sentinel时,其内部做了什么?
- 初始化服务器。但由于其不使用其数据库功能,因此不会载入RDB或AOF文件。
- 将普通的Redis服务器使用的代码换成Sentinel专用的代码。它只允许客户端向其执行PING、SENTINEL、INFO、SUBSTRIBE、UNSUBSTRBE、PSUBSCRIBE、PUNSUBSCRIBE这七个命令,像SET、EVAL这些命令它的命令表中根本就没有载入。
- 初始化Sentinel状态。
- 根据配置文件,初始化Sentinel监视的主服务器列表。
- 创建连向主服务器的网络连接。会创建两个异步连接,一个是命令连接(用于向主服务器发送命令、接受命令),一个是订阅连接(用于订阅主服务器的"_sentinel_:hello"频道)。
Sentinel获取消息
默认情况下:
Sentinel每隔10秒会向主服务器发送INFO命令,获取主服务器信息。
Sentinel每隔10秒会向从服务器发送INFO命令,获取从服务器信息。
Sentinel与服务器建立起订阅连接后,就会订阅_sentinel_:hello频道(SUBSCRIBE _sentinel_:hello)。
Sentinel每隔2秒会向所有监视的主从服务器的_sentinel_:hello频道发送一条消息(PUBLISH _sentinel_:hello ...)。
一个Sentinel发送的消息会被其他Sentinel接受到,用于更新其他Sentinel对发送信息的Sentinel的认知。
检测服务器下线
其分为主观下线和客观下线。
主观下线:Sentinel每隔1秒会像与其创建了命令连接的所有实例(主从服务器、其他sentinel)发送PING命令,判断实例是否在线。返回除了+PONG、-LOADING、-MASTERDOWN之外的回复均认为其主观下线。
客观下线:当一个Sentinel将一个服务器判断为主观下线后,会向同样监视这一服务器的其他Sentinel询问,统计认为其主观下线的数量,当数量达到设定值时,便认为其客观下线了。
选举领头Sentinel
当一个主服务器被判断客观下线后,会选举出一个领头的Sentinel对下线主服务器执行故障转移操作。
选举领头Sentinel的方法是采用Raft算法的实现,主要概括为先到先得,每个Sentinel都会要求其他Sentinel将其设置为局部领头,每个Sentinel只有一次机会设置局部领头,先到先得,票高者得。
参考
- 《Redis的设计与实现》