一、概念介绍
Redis Sentinel,即Redis哨兵,在Redis 2.8版本开始引入,实现了自动化的故障恢复,缺陷是:写操作无法负载均衡,存储能力受到单机的限制。
哨兵主要涉及到下面几个功能,核心功能是主节点的自动故障转移:
1.监控(Monitoring):
哨兵会不断地检查主节点和从节点是否运作正常。
2.自动故障转移(Automatic failover):
当主节点不能正常工作时,哨兵会开始自动故障转移操作,
它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。
3.配置提供者(Configuration provider):
客户端在初始化时,通过连接哨兵来获得当前Redis服务的主节点地址。
4.通知(Notification):
哨兵可以将故障转移的结果发送给客户端。
备注:
监控和自动故障转移功能,使得哨兵可以及时发现主节点故障并完成转移;
而配置提供者和通知功能,则需要在与客户端的交互中才能体现。
(Redis官方文档)
架构图参见下图:
1.第一层的就是哨兵节点:
哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的redis节点,不存储数据。
2.第二层的是数据节点,包括主、从节点,对于主节点和从节点来说,它们都是数据节点。
二、原理介绍
问题1: 既然哨兵节点的主要功能是故障转移,那么哨兵节点就必须要有办法知道这些节点的状态是好的还是坏的,以及哪些是主节点,哪些是从节点,对于这些,哨兵节点是如何操作的呢?
答案:每个哨兵节点维护了3个定时任务,它们分别针对不同节点并且每一个定时任务所做的事情比较固定,定时任务的功能分别如下:
1.哨兵与主从节点之间:通过向主从节点发送info命令获取最新的主从结构;
2.哨兵与哨兵之间:通过发布订阅功能获取其他哨兵节点的信息;
3.保活校验:通过向其他节点发送ping命令进行心跳检测,判断是否下线。
问题2:哨兵节点是如何知道节点下线的呢?
答案:下线在这里分为主观下线和客观下线,哨兵是根据这两种不同的下线方式来对数据节点进行下线判断的。
主观下线:在心跳检测的定时任务中,如果其他节点超过一定时间没有回复,哨兵节点就会将其进行主观下线。
客观下线:哨兵节点在对主节点进行主观下线后,会通过sentinel is-master-down-by-addr命令询问其他哨兵节点该主节点的状态;如果判断主节点下线的哨兵数量达到一定数值,则对该主节点进行客观下线。
(备注:客观下线是主节点才有的概念;如果从节点和哨兵节点发生故障,被哨兵主观下线后,不会再有后续的客观下线和故障转移操作。)
问题3: 哨兵节点是如何进行故障转移的呢?
答案:在判断出来主节点的客观下线之后,会先选举领导者哨兵节点,然后在进行故障转移。
1)选举领导者哨兵节点:当主节点被判断客观下线以后,各个哨兵节点会进行协商,选举出一个领导者哨兵节点,并由该领导者节点对其进行故障转移操作。
监视该主节点的所有哨兵都有可能被选为领导者,选举使用的算法是Raft算法,算法描述如下所示:
Raft算法的基本思路是先到先得。
即在一轮选举中,哨兵A向B发送成为领导者的申请,
如果B没有同意过其他哨兵,则会同意A成为领导者。
一般来说,哨兵选择的过程很快,谁先完成客观下线,一般就能成为领导者。
2)故障转移:
选举出的领导者哨兵,开始进行故障转移操作,该操作大体可以分为3个步骤:
1.在从节点中选择新的主节点:
选择的原则是,首先过滤掉不健康的从节点;
然后选择优先级最高的从节点(由slave-priority指定);
如果优先级无法区分,则选择复制偏移量最大的从节点;
如果仍无法区分,则选择runid最小的从节点。
2. 更新主从状态:
通过slaveof no one命令,让选出来的从节点成为主节点;
并通过slaveof命令让其他节点成为其从节点。
3. 将已经下线的主节点设置为新的主节点的从节点,
当该节点重新上线后,它会成为新的主节点的从节点。
三、使用哨兵的注意点:
1.哨兵节点的数量应不止一个,一方面增加哨兵节点的冗余,避免哨兵本身成为高可用的瓶颈;另一方面减少对下线的误判。此外,这些不同的哨兵节点应部署在不同的物理机上。
2.哨兵节点的数量应该是奇数,便于哨兵通过投票做出“决策”:领导者选举的决策、客观下线的决策等。
3.各个哨兵节点的配置应一致,包括硬件、参数等;此外,所有节点都应该使用ntp或类似服务,保证时间准确、一致。
参考资料:
https://redis.io/topics/sentinel