Redis6.x学习笔记(五)哨兵
阅读原文时间:2021年06月10日阅读:3

最近学习Redis6.x,特做笔记以备忘,与大家共学。课程是从私塾在线下载的,他们把架构师课程都放出来了,大家可以去下载学习,不要钱的,地址是http://t.hk.uy/eK7,课程很不错,值得学习!关键是不要钱,嘻嘻!

哨兵是Redis 复制集 集群的重要组件,主要实现:

1:集群监控:监控主从数据库运行是否正常
2:故障转移:当主数据库出现故障时,自动将从数据库转换成为主数据库
3:配置中心:客户端通过连接哨兵来获得当前Redis服务的主节点地址
4:消息通知:哨兵可以将故障转移的结果发送给客户端

注意:使用Redis-sentinel,redis实例必须在非集群模式下运行

建立一个sentinel.conf文件,里面设置要监控的主数据库的名字,形如:
sentinel monitor 监控的主数据库的名字 127.0.0.1 6380 1

表示哨兵判断主节点是否发生故障的最低票数
(1)这个文件的内容,在运行期间会被sentinel动态进行更改
(2)可以同时监控多个主数据库,一行一个配置即可


1:bind:服务监听地址,用于客户端连接,默认本机地址
2:protected-mode:安全保护模式
3:port:监听的端口号
4:daemonize:是否以后台daemon方式运行
5:pidfile:pid文件位置
6:logfile:log文件位置
7:dir:工作目录
8:sentinel monitor <master-name> <ip> <port> <quorum>:
    设置要监控的master服务器
9: sentinel auth-pass <master-name> <password>:连接master服务的密码
10: sentinel down-after-milliseconds <master-name> <milliseconds>:
    指定多少毫秒之后,主节点没有应答哨兵,此时哨兵主观上认为主节点下线
11: sentinel parallel-syncs <master-name> <nums>:
    表示允许并行同步的slave个数,当Master挂了后,哨兵会选出新的Master,
    此时,剩余的slave会向新的master发起同步数据
12: sentinel failover-timeout <master-name> <milliseconds>:
    故障转移的超时时间,进行故障转移时,如果超过设置的毫秒,
    表示故障转移失败
13: sentinel notification-script <master-name> <script-path> :
    配置当某一事件发生时所需要执行的脚本
14: sentinel client-reconfig-script <master-name> <script-path>:
    客户端重新配置主节点参数脚本

哨兵互相之间的相互自动发现,是通过redis的pub/sub系统实现的,每个哨兵都会往__sentinel__:hello这个channel里发送一个消息,这时候所有其他哨兵都可以消费到这个消息,并感知到其他的哨兵的存在。

每隔两秒钟,每个哨兵都会往自己监控的某个master+slave对应的__sentinel__:hello channel里发送一个消息,内容是自己的host、ip和runid还有对这个master的监控配置。

每个哨兵也会去监听自己监控的每个master+slaves对应的__sentinel__:hello channel,然后去感知到同样在监听这个master+slave的其他哨兵的存在。

每个哨兵跟其他哨兵交换对master的监控配置,互相进行监控配置的同步

quorum:确认客观下线的最少的哨兵数量
majority:授权进行主从切换的最少的哨兵数量

每次一个哨兵要做主备切换,首先需要quorum数量的哨兵认为master客观下线,然后选举出一个哨兵来做切换,这个哨兵还需要得到majority哨兵的授权,才能正式执行切换

当主节点被判断客观下线以后,各个哨兵节点会进行协商,选举出一个领导者哨兵节点,并由该领导者节点对其进行故障转移操作。

监视该主节点的所有哨兵都有可能被选为领导者,选举使用的算法是Raft算法

Raft算法的基本思路是先到先得:即在一轮选举中,哨兵A向B发送成为领导者的申请,如果B没有同意过其他哨兵,则会同意A成为领导者

哨兵基本原理之故障转移

选举出的领导者哨兵,开始进行故障转移操作,大体可以分为3个步骤:

1:在从节点中选择新的主节点:选择的原则是,首先过滤掉不健康的从节点;然后选择优先级最高的从节点(由slave-priority指定);如果优先级无法区分,则选择复制offset最大的从节点;如果仍无法区分,则选择runid最小的从节点

2:更新主从状态:通过slaveof no one命令,让选出来的从节点成为主节点;并通过slaveof命令让其他节点成为其从节点

3:将已经下线的主节点设置为新的主节点的从节点,当其重新上线后,它会成为新的主节点的从节点

configuration epoch

新的master选出过后,执行切换的那个哨兵,会从要切换到的新master那里得到一个configuration epoch,这就是一个version号,每次切换的version号都必须是唯一的。

如果第一个选举出的哨兵切换失败了,那么其他哨兵,会等待failover-timeout时间,然后接替继续执行切换,此时会重新获取一个新的configuration epoch,作为新的version号

Configuration传播

哨兵完成master切换之后,会在自己本地更新生成最新的master配置,然后同步给其他的哨兵,就是通过之前说的pub/sub消息机制。

这时version号就很重要了,因为各种消息都是通过一个channel去发布和监听的,所以一个哨兵完成一次master的切换之后,新的master配置是跟着新的version号的。

其他的哨兵都是根据版本号的大小来更新自己的master配置的

1:哨兵节点的数量应为多个,哨兵本身应该集群,保证高可用
2:哨兵节点的数量应该是奇数
3:各个哨兵节点的配置应一致
4:如果哨兵节点部署在Docker等容器里面,尤其要注意端口的正确映射
5:哨兵集群+主从复制,并不能保证数据零丢失

我会持续的把我学习Redis6.x过程的笔记记录下来,跟大家一起学习。希望能坚持下去!