一、主从模式存在的问题
- 主节点发生故障时,进行主备切换的过程是复杂的,需要完全的人工参与,导致故障恢复时间无法保障,即高可用问题;
- 主节点可以将读压力分散出去,但写压力和存储压力是无法被分担的,还是受到单机的限制;
二、什么是哨兵模式
哨兵模式(Redis Sentinel)是用来解决主从模式中的高可用问题的,用于监控 Redis 主从架构中的主节点和从节点,可自动处理主节点故障问题,可以确保 Redis 服务的可用性和健壮性;
相关名词解释
由上图可以看出,哨兵节点就是一个 redis-sentinel 进程;
Redis Sentinel 是一个分布式架构,其中包含若干个 Sentinel 节点和 Redis 数据节点,每个 Sentinel 节点会对数据节点和其余 Sentinel 节点进行监控,当它发现节点不可达时,会对节点做下线表示;如果下线的是主节点(主观下线),它还会和其他的 Sentinel 节点进行 "协商",当大多数 Sentinel 节点对主节点不可达这个结论达成共识之后(客观下线),它们会在内部 "选举" 出一个领导节点来完成自动故障转移的工作,同时将这个变化实时通知给 Redis 应用方;整个过程是完全自动的,不需要人工介入;
哨兵模式架构图
三、通过哨兵解决主节点故障问题
哨兵模式相比主从模式多了若干个哨兵节点,哨兵节点用于实现监控数据节点,当主节点出现故障时,Redis Sentinel 能自动完成故障发现和故障转移,并通知应用方,从而实现真正的高可用;
- 主节点故障,从节点与主节点的连接中断,主从复制停止,此时只可读不可写;
- 哨兵节点通过监控发现主节点故障,并通过与其他哨兵节点协商,达成主节点故障的共识,(防止出故障的是该哨兵节点);
- 哨兵节点之间使用 Raft 算法选举出一个领导 leader;
- 哨兵领导 leader 负责故障转移:在从节点中选取一个节点作为新的主节点,并让其他节点同步新的主节点,并通知应用层转移到新的主节点;
四、选举原理
假设该哨兵模式包含 1 个主节点,2 个从节点,3 个哨兵节点
1. 主观下线
当主节点宕机后,此时 3 个哨兵节点与主节点之间的心跳包就没有了,此时,在 3 个哨兵节点看来,主节点出现故障,即 3 个哨兵节点在各自的主观判断上认为主节点故障
2. 客观下线
此时 3 个哨兵节点对主节点故障这个事情进行投票,当任为故障的票数 >= 配置的法定票数时,此时就认为主节点真的出现故障了,即客观下线;
sentinel monitor redis-master 101.42.44.62(主节点ip) 2(法定票数)
这里的 2 就是配置的法定票数;
3. 选出 leader
当主节点客观下线后,就需要在剩余从节点中选出一个作为新的主节点,这个工作不需要所有哨兵节点都参与,只需哨兵们选出一个 leader,leader 负责这个过程,选取 leader 的过程涉及到 Raft 算法;
Raft 算法的核心就是 "先下手为强",谁率先发出了拉票请求,谁就有更大的概率成为 leader,具体选出的哪个节点是 leader,这个并不重要;
4. 选出新的主节点
leader 选出新的主节点的挑选规则:
- 比较优先级:优先级越高(数值小)的优先上位,优先级是在配置文件中的配置项 slave-priority 或 replica-priority 中配置的;
- 比较 replication offset,谁的偏移量越多,说明谁同步的主节点的数据越多,则越多的上位;
- 当 1 和 2 相同时,此时选取哪个从节点作为新的主节点都是一样的,此时就根据 run id(redis-server 进程启动时随机生成的 id 值),谁的 run id 越小,谁上位;
当选出新的主节点之后,leader 会操纵该节点先执行 slave no one 成为真正的主节点,然后 leader 会操纵其余的从节点,让他们都依附于这个新的主节点;
5. 注意事项
- 哨兵节点不能只有一个,否则哨兵节点宕机之后,会影响系统的可用性;
- 哨兵节点最好是奇数个,方便选取 leader;
- 哨兵节点不负责存储数据,只负责监控数据节点,仍然是数据节点存储数据;
- 哨兵 + 主从复制不能提高数据的存储容量,当我们需要存的数据接近或者超过机器的物理内存,这样的结构就难以胜任了,此时就需要采用集群模式;