概括
Sentinel 是 Redis 高可用的一种解决方案:Sentinel 系统由一个或多个 Sentinel 示例组成,可以监控任意多个主服务器以及这些主服务器下的所有从服务器。若被监视的主服务器进入下线状态时(宕机或者进程被 kill 等情况导致),则会自动将下线主服务器下的某个从服务器中升级为新的服务器,由这个新的服务器代替已下线的主服务器继续处理命令请求。
图示过程:
若期间 Server1 重新上线,它将被 Sentinel 降级为 Server2 的从服务器。
启动并初始化 Sentinel
启动一个 Sentinel 可以使用命令:
$ redis-sentinel /path/to/your/sentinel.conf
或者
$ redis-server /path/to/your/sentinel.conf --sentinel
当启动一个 sentinel 时,需要执行以下步骤:
- 初始化服务器
- 将普通 Redis 服务器使用代码替换成 Sentinel 专用代码
- 初始化 Sentinel 状态
- 根据给定的配置文件,初始化 Sentinel 的监视主服务器列表
- 创建连向主服务器的网络连接:创建两个连接(异步连接)。一个是命令连接,专门用于向主服务器发送命令,并接收命令回复。另一个是订阅连接,这个专门用于订阅主服务器_sentinel_:hello 频道。
获取主服务器信息
Sentinel 默认会以每十秒一次的频率,通过命令连接向被监视的主服务器发送 INFO 命令,并通过分析 INFO 命令的回复来获取主服务器的当前信息。
通过分析 INFO 指令的回复信息,可以得到:
- 主服务器本身的信息,包括 run_id 域记录的服务器运行id,以及 role 域记录的服务器角色
- 主服务器下面的所有从服务器的信息,无需用户提供从服务器的地址信息,就可以自动发现从服务器。
获取从服务器信息
当 Sentinel 发现新的从服务器出现时,Sentinel 除了会为这个新的从服务器创建相应的实例结构之外,Sentinel 还会创建连接到从服务器的命令连接和订阅连接。
当 Sentinel 与从服务器建立连接之后,会以每十秒一次的频率通过命令连接向从服务器发送INFO命令,以获取从服务器的信息。
根据INFO 指令的回复信息,可以得到:
- 从服务器的运行ID run_id
- 从服务器的角色 role
- 主服务器的ip地址 master_host,以及主服务器的端口号master_port
- 主服务器的连接状态master_link_status
- 从服务器的优先级slave_priority
- 从服务器的复制偏移量slave_repl_offset
如图:
通过命令连接发送和订阅连接接收信息
对于监视用一个服务器的多个 Sentinel 来说, 他们会以没两秒一次的频率,通过向被监视服务器的_sentinel_:hello频道发送消息来向其他 Sentinel 宣告自己的存在。
检测主观下线状态
在默认情况下,Sentinel 会以每秒一次的频率向所有与它创建了命令连接的示例(主、从服务器、其他sentinel)发送PING命令,并通过实例返回的PING命令回复判断实例是否在线。
PING命令的回复分为两种:
- 有效回复:实例返回 +PONG 、-LOADING 、-MASTERDOWN 三种回复的其中一种。
- 无效回复:实例返回除 +PONG 、-LOADING 、-MASTERDOWN 三种之外的其他回复,或者在指定时间内没有返回任何回复。
若在指定时间内一直向 sentinel 返回无效回复,那么将会判断次实例已经进入主观下线状态。
检测客观下线状态
当 Sentinel 将一个主服务器判断为主观下线之后,为了确认主服务器是否真的下线,它会向同样监视这一主服务器的其他 sentinel 进行询问,当 从其他的 Sentinel 那里接收到足量已下线的判断后,Sentinel 就会主服务器判断为客观下线,并对主服务器进行故障转移操作。
故障转移
在故障转移之前会进行一场 Sentinel 选举,选举出来的 Sentinel 负责对客观下线的主服务器进行故障转移。
- 在已下线的主服务器属下的所有从服务器中,挑选一个从服务器,并将其转换为主服务器。
- 将已下线的主服务器属下的所有从服务器中改为复制新的主服务器
- 将已下线的主服务器设置为新的主服务器的从服务器,当这个旧的主服务器重新上线,它将会成为新的主服务器的从服务器。