哨兵模式可极大地提高Redis的可用性。
哨兵的作用
- 监控 (哨兵可时刻监测Redis主节点和从节点的工作状态)
- 通知 (当检测到某一个redis实例运行出错时,哨兵可通知系统管理员或其他计算机程序)
- 自动故障转移 (automatic failover) (若主节点运行出错,哨兵可触发故障转移机制,将某个从节点选举为新的主节点,并通知应用程序连接到新的主节点)
- 提供配置
哨兵集群
Redis的哨兵模式本质上是集群的。
哨兵模式在设计之初就要求,在此模式下,应有多个哨兵进程协同工作。
哨兵集群的优势
- 多个哨兵一致同意某个主节点已经不可用时才会触发故障检测机制,从而减少“谎报军情”的情况
- 即使某些哨兵进程不可用,其余的哨兵也可以继续工作
快速开始
启动哨兵:
redis-sentinel /path/to/sentinel.conf
或 redis-server /path/to/sentinel.conf --sentinel
哨兵启动后默认监听26379端口
部署哨兵的注意点: 1. 至少需要3个哨兵实例 2. 哨兵所在的环境应相互独立 3. 将哨兵模式和docker 或其他网络地址转换、端口映射工具混用时要小心
配置哨兵
典型的哨兵配置如下:
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 resque 192.168.1.3 6380 4
sentinel down-after-milliseconds resque 10000
sentinel failover-timeout resque 180000
sentinel parallel-syncs resque 5
你只需给出需要监控的主节点,为每个主节点(可能有数量不一的从节点)起一个独有的名字。无需为哨兵提供从节点的信息(哨兵会自动获取)。哨兵会自动更新配置文件,添加与从节点有关的信息(因此,该信息在哨兵重启后不会丢失)。当发生故障转移,从节点被推举为主节点,以及新的哨兵被发现时,哨兵也会自动更新配置信息。
以上配置监控了两组redis实例,每组实例包含一个主节点和数量不定的从节点。一组节点被命名为mymaster,另一组被命名为resque。
sentinel monitor
语句格式如下:
sentinel monitor <master-group-name> <ip> <port> <quorum>
配置含义
sentinel monitor... --> 告诉redis监控,ip为127.0.0.1,端口号为6378,名为mymaster的主节点,quorum设为2。
quorum的含义: 确认主节点不可达需要经过多少哨兵同意 (从而将该主机标记为失效,并触发故障转移机制)
若多数哨兵进程之间不能通信,则不会触发故障转移机制。
其他哨兵相关选项
sentinel <option_name> <master_name> <option_value>
- down-after-milliseconds
- parallel-syncs
高级概念
SDOWN and ODOWN failure state (主观下线和客观下线)
- 主观下线(Subjectively Down, 简称 SDOWN) 单个 Sentinel 实例对服务器做出的下线判断。
- 客观下线(Objectively Down, 简称 ODOWN) 多个 Sentinel 实例在对同一个服务器做出 SDOWN 判断, 并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后, 一致得出的服务器下线判断。
若在配置文件内 is-master-down-after-milliseconds 参数设置的时间段内,某个哨兵向某个主节点连续发送PING消息,但均未收到有效的回复,则该哨兵会对该节点做出下线判断。
有效的回复包括: 1. PING replied with +PONG. 2. PING replied with -LOADING error. 3. PING replied with -MASTERDOWN error.
SDOWN状态不足以触发故障转移:该状态只意味着某一个哨兵认为某个Redis实例不可达。触发故障转移前必须先到达ODOWN状态。
从SDOWN转变为ODOWN状态无需哨兵之间运行某种算法,达成一致,它们之间仅需采取一种协商(gossip)的方式:在一个既定的时间段内当某个哨兵从足够多的哨兵那里收到通知,知道一个主节点发生故障了,该哨兵就会将该主节点的SDOWN状态转变为ODOWN状态。如果之后,多个哨兵之间没有出现这种gossip,ODOWN旗标就会被清除。
若要真的开始故障转移,哨兵必须根据一种严格的授权机制得到所有哨兵的多数投票后才会被推举为具体执行者,但进行故障转移之前必须先到达ODOWN状态。
客观下线条件(ODOWN)只适用于主服务器,任何其他类型的 Redis 实例(从节点、哨兵)只会出现主观下线(SDOWN)状态。 Sentinel 在将它们判断为下线前不需要进行协商, 所以从服务器或者其他 Sentinel 永远不会达到客观下线条件。
只要一个 Sentinel 发现某个主服务器进入了客观下线状态, 这个 Sentinel 就可能会被其他 Sentinel 推选出, 并对失效的主服务器执行自动故障迁移操作。
不过,SDOWN状态也是有意义的。例如,哨兵在进行故障转移操作时不会将处于SDOWN状态的从节点推选为主节点。
每个Sentinel实例都执行的定时任务
1. 每个 Sentinel 以每秒钟一次的频率向它所知的主服务器、从服务器以及其他 Sentinel 实例发送一个 PING 命令。
2. 如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 那么这个实例会被 Sentinel 标记为主观下线。 一个有效回复可以是: +PONG 、 -LOADING 或者 -MASTERDOWN 。
3. 如果一个主服务器被标记为主观下线, 那么正在监视这个主服务器的所有 Sentinel 要以每秒一次的频率确认主服务器的确进入了主观下线状态。
4. 如果一个主服务器被标记为主观下线, 并且有足够数量的 Sentinel (至少要达到配置文件指定的数量)在指定的时间范围内同意这一判断, 那么这个主服务器被标记为客观下线。
5. 在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有主服务器和从服务器发送 INFO 命令。 当一个主服务器被 Sentinel 标记为客观下线时, Sentinel 向下线主服务器的所有从服务器发送 INFO 命令的频率会从 10 秒一次改为每秒一次。
6. 当没有足够数量的 Sentinel 同意主服务器已经下线, 主服务器的客观下线状态就会被移除。 当主服务器重新向 Sentinel 的 PING 命令返回有效回复时, 主服务器的主观下线状态就会被移除。