一:为什么产生哨兵
redis的主从复制模式 ,一个主,多个备可以实现数据的容灾,即主节点故障之后,备节点执行slave no one 可以升主,做到数据尽量不丢失,另一个优点时扩展主节点的读能力,但也存在如下问题:
1:主节点故障,需要手动将备节点升为主节点,同时还需要命令将其他的备节点去复制新的主节点,整个过程需要人工干预,无法做到自动化,缺乏高可用
2:主节点写能力以及存储能力受主节点限制
Redis的哨兵模式,就是在主从模式的基础上,额外部署若干独立的哨兵进程,通过哨兵进程去监视者Redis主从节点的状态,一旦发现主节点宕机,则哨兵可以重新从剩余slave节点中推选一个新的节点并将其升级为master节点,以此保证整个系统功能可以正常使用。
哨兵负责三个任务:监控,选主(选择主库)和通知。
- 监控:监控是指哨兵进程运行时,周期性(默认1秒)给所有主从节点发送 PING 命令,当主从节点收到 PING 命令后,会发送一个响应命令给哨兵,这样就可以检测他们是否仍然在线运行。
- 从库没有在规定时间内响应哨兵的PING命令,哨兵就会把它标记为"下线状态";
- 主库没有在规定时间呢响应哨兵的PING命令,哨兵就会判定主库下线启动选主流程。
- 通知:哨兵将选出的新主库连接信息发给其他从库,从库和新主库建立连接,执行replicaof命令,复制数据。同时,哨兵会把新主库的连接信息通知给客户端,让它们将操作请求发送给新主库上
- 主节点故障转移:实现从节点晋升为主节点并维护后续正确的主从关系
- 配置提供者: 在Redis Sentinel结构中,客户端在初始化的时候连接的时Sentinel节点集合,从中获取主节点信息
同时看到,Redis Sentinel 包含若个Sentinel节点,还有下面2个好处:
a. 对于节点的故障判断是由多个Sentinel节点共同完成,这样可以有效地防止误判
b. Sentinel节点集合是由若干个Sentinel节点组成,这样使个别Sentinel节点不同用,整个Sentinel节点集合依然时健壮的
二安装和部署
2.1:部署主从节点,参考前面redis复制章节
2.2:部署Sentinel节点,一般部署3个哨兵节点
redis_sentinel_26800.conf:
port 26800
daemonize yes
logfile "/mnt/d/ubuntu_dir/redis/redis/logs/redis_sentinel_26800.log"
dir "/mnt/d/ubuntu_dir/redis/redis/data"
sentinel monitor mymaster 127.0.0.1 6800 2
# Generated by CONFIG REWRITE
protected-mode no
latency-tracking-info-percentiles 50 99 99.9
pidfile "/var/run/redis.pid"
启动哨兵节点:
redis-sentinel redis_sentinel_26800.conf 或者redis-server redis_sentinel_26800.conf --sentinel
另外2个节点改一下端口号一样配置
启动后节点监控如下:

三 redis哨兵专属API
3.1:展示所有被监控的主节点状态以及相关的统计信息
sentinel masters
3.2 : 展示指定被监控的主节点状态以及相关的统计信息
sentinel master <master name>
3.3:展示指定被监控的从节点状态以及相关的统计信息
sentinel slavers <master name>
3.4:展示指定<master name>sentinel节点集合
sentinel sentinels mymaster
3.5: 查询指定<master name> 主节点的IP地址和端口
Sentinel get-master-addr-by-name <master name>
3.6: 对<master name>主节点进行强制故障转移
sentinel failover mymaster
3.7: 当前sentinel节点对符合<pattern>主节点的配置进行重置,包含清除主节点的相关状态,重新发现从节点和sentinel节点
sentinel reset mymaster
3.8:检查当前可达的sentinel节点总数是否达到<quorum>的个数
sentinel chquorum mymaster
3.9 将sentinel节点的配置强制刷到磁盘上
sentinel flushconfig
3.10 取消当前sentinel节点对于指定<master name>主节点的监控
sentinel remove mymaster
3.11 监控主节点
Sentinel monitor mymaster ip port quorum
3.12 动态修改sentinel节点配置选项
sentinel set <master name>
3.13 sentinel节点之间用来交换对主节点是否下线的判断,还可以作为sentinel领导者选举的通信方式
sentinel is-master-down-by-addr
四 哨兵的实现原理
4.1 三个定时监控任务
a:每隔 10 秒,每隔 Sentinel 节点会向主节点和从节点发送 info 命令获取最新的拓扑图
b:每隔 2 秒,每个 Sentinel 节点会向 Redis 数据节点的 __sentinel__:hello 频道发送该 Sentinel 节点对于主节点的判断以及当前 Sentinel 节点的信息,同时每个 Sentinel 节点也会订阅该频道,来了解其他 Sentinel 节点以及它们对主节点的判断
工作内容
- 发现新的 Sentinel 节点:通过订阅主节点的 __sentinel__:hello 了解其他 Sentinel 节点信息,如果是新加入的 Sentinel 节点,将该 Sentinel 节点信息保存起来,并于该 Sentinel 节点创建连接。
- Sentinel 节点之间交换主节点的状态,作为后面客观下线以及领导者选举的依据。

c:每隔 1 秒,每个 Sentinel 节点会向主节点、从节点、其余 Sentinel 节点发送一条 ping 命令做一次心跳检测,来确认这些节点当前是否可达
通过每 1 秒定时任务,Sentinel 节点对主节点、从节点、其余 Sentinel 节点都建立起连接,实现了对每个节点的监控,这个定时任务是判断节点是否可用的重要依据。

4.2 主观下线和客观下线
4.2.1主观下线
每个sentinel节点会每隔1s对主节点、从节点、其他的sentinel节点发送ping命令做心跳检测,当这些节点超过down-after-milliseconds没有进行有效回复,哨兵就会对该节点做失败判定

4.2.2客观下线
a. 当sentinel 哨兵节点将 master 标记为主观下线后,会向其余所有的 sentinel 发送sentinel is-master-down-by-addr消息,询问其他sentinel是否同意该master下线
发送命令:sentinel is-master-down-by-addr <ip> <port> <current_epoch> <runid>
ip:主观下线的服务ip
port:主观下线的服务端口
current_epoch:sentinel的纪元
runid:*表示检测服务下线状态,如果是sentinel的运行id,表示用来选举领头sentinel
b.每个sentinel收到命令之后,会根据发送过来的 ip和port 检查自己判断的结果,回复自己是否认为该master节点已经下线了
回复内容主要包含三个参数(由于上面发送的runid参数是*,这里先忽略后两个参数)
down_state(1表示已下线,0表示未下线)
leader_runid(领头sentinal id)
leader_epoch(领头sentinel纪元)
c .sentinel收到回复之后,如果同意master节点进入主观下线的sentinel数量大于等于quorum,则master会被标记为客观下线,即认为该节点已经不可用。
d. 在一般情况下,每个 Sentinel 每隔 10s 向所有的Master,Slave发送 INFO 命令。当Master 被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次
作用:发现最新的集群拓扑结构
4.3 基于Raft算法领导者Sentinel 节点的选举
到现在为止,已经知道了master客观下线,那就需要一个sentinel来负责故障转移,那到底是哪个sentinel节点来做这件事呢?需要通过选举实现,具体的选举过程如下:
(1)判断客观下线的sentinel节点向其他 sentinel 节点发送
SENTINEL is-master-down-by-addr ip port current_epoch runid
注意:这时的runid是自己的run id,每个sentinel节点都有一个自己运行时id
(2)目标sentinel回复是否同意master下线并选举领头sentinel,选择领头sentinel的过程符合先到先得的原则。举例:sentinel1判断了客观下线,向sentinel2发送了第一步中的命令,sentinel2回复了sentinel1,说选你为领头,这时候sentinel3也向sentinel2发送第一步的命令,sentinel2会直接拒绝回复
(3)当sentinel发现选自己的节点个数超过 majority 的个数的时候,自己就是领头节点
(4)如果没有一个sentinel达到了majority的数量,等一段时间,重新选举
4.4故障转移
有了领头sentinel之后,下面就是要做故障转移了,故障转移的一个主要问题和选择领头sentinel问题差不多,到底要选择哪一个slaver节点来作为master呢?按照我们一般的常识,我们会认为哪个slave节点中的数据和master中的数据相识度高哪个slaver就是master了,其实哨兵模式也差不多是这样判断的,不过还有别的判断条件,详细介绍如下:
(1)在进行选择之前需要先剔除掉一些不满足条件的slaver,这些slaver不会作为变成master的备选
剔除列表中已经下线的从服务
剔除有5s没有回复sentinel的info命令的slave
剔除与已经下线的主服务连接断开时间超过 down-after-milliseconds * 10 + master宕机时长 的slaver
(2)选主过程:
① 选择优先级最高的节点,通过sentinel配置文件中的replica-priority配置项,这个参数越小,表示优先级越高
② 如果第一步中的优先级相同,选择offset最大的,offset表示主节点向从节点同步数据的偏移量,越大表示同步的数据越多
③ 如果第二步offset也相同,选择run id较小的
4.5 修改配置
修改配置:
新的master节点选择出来之后,还需要做一些事情配置的修改,如下:
(1)领头sentinel会对选出来的从节点执行slaveof no one 命令让其成为主节点
(2)领头sentinel 向别的slave发送slaveof命令,告诉他们新的master是谁谁谁,你们向这个master复制数据
(3)如果之前的master重新上线时,领头sentinel同样会给起发送slaveof命令,将其变成从节点

2151

被折叠的 条评论
为什么被折叠?



