Redis的主从复制模式下, 一旦主节点由于故障不能提供服务, 需要人工将从节点晋升为主节点, 同时还要通知应用方更新主节点地址 ,Redis从2.8开始正式 提供了Redis Sentinel(哨兵) 架构来解决这个问题 。
Redis Sentinel 是一个分布式架构, 其中包含若干个Sentinel节点和Redis数据节点, 每个Sentinel节点会对数据节点和其余Sentinel节点进行监控, 当它发现节点不可达时, 会对节点做下线标识。 如果被标识的是主节点, 它还会和其他Sentinel节点进行"协商", 当大多数Sentinel节点都认为主节点不可达时, 它们会选举出一个Sentinel节点来完成自动故障转移的工作, 同时会将这个变化实时通知给Redis应用方。 整个过程完全是自动的, 不需要人工来介入。
哨兵功能
-
监控: Sentinel节点会定期检测Redis数据节点、 其余Sentinel节点是否可达。
-
通知: Sentinel节点会将故障转移的结果通知给应用方。
-
主节点故障转移: 实现从节点晋升为主节点并维护后续正确的主从关系。
-
配置提供者: 在Redis Sentinel结构中, 客户端在初始化的时候连接的是Sentinel节点集合, 从中获取主节点信息。
配置哨兵
vim sentinel.conf
sentinel monitor <master-name> <ip> <port> <quorum>
quorum 定义了投票的数量,用于决定是否认为主服务器(master)故障或者宕机。当 Sentinel 集群中达到或超过 quorum 数量的 Sentinel 实例都认为主服务器下线时,它们会进行故障转移并选举新主服务器。如果没有达到或超过 quorum 数量的 Sentinel 实例都认为主服务器下线,那么故障转移不会发生。
sentinel down-after-milliseconds <master-name> <times>
ping 命令来判断Redis数据节点和其余Sentinel节点是否可达, 如果超过了 down-after-milliseconds
配置的时间且没有有效的回复, 则判定节点不可达, <times>(单位为毫秒) 就是超时时间。
sentinel parallel-syncs <master-name> <nums>
选出新的主节点, 原来的从节点会向新的主节点发起复制操作, parallel-syncs
就是用来限制在一次故障转移之后, 每次向新的主节点发起复制操作的从节点个数。
sentinel failover-timeout <master-name> <times>
failover-timeout
通常被解释成故障转移超时时间, 但实际上它作用于故障转移的各个阶段:
a) 选出合适从节点。
b) 晋升选出的从节点为主节点。
c) 命令其余从节点复制新的主节点。
d) 等待原主节点恢复后命令它去复制新的主节点。failover-timeout的作用具体体现在四个方面:
1) 如果Redis Sentinel对一个主节点故障转移失败, 那么下次再对该主节点做故障转移的起始时间是failover-timeout的2倍。
2) 在b) 阶段时, 如果Sentinel节点向a) 阶段选出来的从节点执行slaveof no one一直失败(例如该从节点此时出现故障) , 当此过程超过failover-timeout时, 则故障转移失败。
3) 在b) 阶段如果执行成功, Sentinel节点还会执行info命令来确认a)阶段选出来的节点确实晋升为主节点, 如果此过程执行时间超过failovertimeout时, 则故障转移失败。
4) 如果c) 阶段执行时间超过了failover-timeout(不包含复制时间) ,则故障转移失败。 注意即使超过了这个时间, Sentinel节点也会最终配置从节点去同步最新的主节点。
sentinel auth-pass <master-name> <password>
auth-pass
配置通过添加主节点的密码
sentinel notification-script <master-name> <script-path>
notification-script
的作用是在故障转移期间, 当一些警告级别的Sentinel事件发生(指重要事件, 例如-sdown: 客观下线、 -odown: 主观下线) 时, 会触发对应路径的脚本, 并向脚本发送相应的事件参数。
sentinel client-reconfig-script <master-name> <script-path>
client-reconfig-script
的作用是在故障转移结束后, 会触发对应路径的脚本, 并向脚本发送故障转移结果的相关参数。
当故障转移结束, 每个Sentinel节点会将故障转移的结果发送给对应的脚本, 具体参数如下:
<master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
-
<master-name>: 主节点名。
-
<role>: Sentinel节点的角色, 分别是leader和observer, leader代表当前Sentinel节点是领导者, 是它进行的故障转移; observer是其余Sentinel节点。
-
<from-ip>: 原主节点的ip地址。
-
<from-port>: 原主节点的端口。
-
<to-ip>: 新主节点的ip地址。
-
<to-port>: 新主节点的端口。
有关 notification-script
和 client-reconfig-script
有几点需要注意:
-
<script-path>必须有可执行权限。
-
<script-path>开头必须包含shell脚本头(例如#! /bin/sh) , 否则事件发生时Redis将无法执行脚本产生如下错误:-script-error /opt/sentinel/notification.sh 0 2
-
Redis规定脚本的最大执行时间不能超过60秒, 超过后脚本将被杀掉。
-
如果shell脚本以exit 1结束, 那么脚本稍后重试执行。 如果以exit 2或者更高的值结束, 那么脚本不会重试。 正常返回值是exit 0。
-
如果需要运维的Redis Sentinel比较多, 建议不要使用这种脚本的形式来进行通知, 这样会增加部署的成本。
启动哨兵
redis-sentinel sentinel.conf
redis-server sentinel.conf --sentinel
CLI
redis-cli -p 26379
进入 sentinel 命令行
sentinel masters
展示所有被监控的主节点状态以及相关的统计信息
sentinel master<master name>
展示指定<master name>的主节点状态以及相关的统计信息
sentinel slaves<master name>
展示指定<master name>的从节点状态以及相关的统计信息
sentinel sentinels<master name>
展示指定<master name>的Sentinel节点集合(不包含当前Sentinel节点)
sentinel get-master-addr-by-name<master name>
返回指定<master name>主节点的IP地址和端口
sentinel reset<pattern>
当前Sentinel节点对符合<pattern>(通配符风格) 主节点的配置进行重置, 包含清除主节点的相关状态(例如故障转移) , 重新发现从节点和Sentinel节点 。
sentinel failover<master name>
对指定<master name>主节点进行强制故障转移
sentinel ckquorum<master name>
检测当前可达的Sentinel节点总数是否达到<quorum>的个数
sentinel flushconfig
将Sentinel节点的配置强制刷到磁盘上
sentinel remove<master name>
取消当前Sentinel节点对于指定<master name>主节点的监控
sentinel monitor<master name><ip><port><quorum>
这个命令和配置文件中的含义是完全一样的, 只不过是通过命令的形式来完成Sentinel节点对主节点的监控
sentinel set<master name>
动态修改Sentinel节点配置选项
sentinel is-master-down-by-addr
Sentinel节点之间用来交换对主节点是否下线的判断
选举的逻辑:
-
哨兵之间进行通信:所有的哨兵实例会互相通信,以了解主服务器和从服务器的状态,并共同监视整个 Redis 集群。
-
监测主服务器状态:每个哨兵会定期向主服务器和从服务器发送心跳检测,以确保它们处于可用状态。如果某个哨兵在一定时间内没有收到来自主服务器的心跳响应,它将判定主服务器宕机。
-
故障切换选举:当主服务器被标记为宕机后,所有的哨兵将通过一个投票过程进行故障切换选举。
-
哨兵开始投票:每个哨兵开始对候选的从服务器进行投票,以选出新的主服务器。这些从服务器必须满足一定的条件,如复制偏移量、复制连接状态等。
-
选举新的主服务器:如果有一个候选的从服务器获得了超过 quorum(仲裁数)的支持票数,则该从服务器将被选举为新的主服务器。
-
更新配置:一旦新的主服务器被选举出来,所有的哨兵将更新其配置,使其将新的主服务器作为监视对象,并将其他从服务器配置为新主服务器的从服务器。
-
-
配置广播:一旦配置更新完成,哨兵会将新的配置信息广播给所有的 Redis 客户端和其他哨兵,以保持整个集群的一致性。
通过这个选举逻辑,Redis Sentinel 实现了自动故障转移和高可用性。即使主服务器宕机,哨兵能够快速选举出新的主服务器,并使整个 Redis 集群继续正常工作。
Tips
-
主机恢复后只能做新主机的从机。
-
Sentinel节点不应该部署在一台物理"机器"上。
-
部署至少三个且奇数个的Sentinel节点。
-
如果Sentinel节点集合监控的是同一个业务的多个主节点集合, 那么使用一套Sentinel 、 否则一般建议采用多套Sentinel 方案 。
参考资料:《Redis 开发与运维》