哨兵

哨兵至少需要 3 个实例,来保证自己的健壮性

当大多数Sentinel节点都认为主节点不可达时,它们会选举出一个Sentinel节点来完成自动故障转移的工作,同时会将这个变化实时通知给Redis应用方

哨兵(sentinel) 是一个分布式系统,你可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(gossip protocols)来接收关于Master是否下线的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master

2020224134359 屏幕截图 2020-10-07 155936

高可用读写分离:

屏幕截图 2020-10-08 144313

原理

三个定时任务:

sdown与odown:

sentinel领导节点选举:通过raft算法 由sentienl领导节点进行故障转移的操作

故障转移

屏幕截图 2020-10-08 143210

数据丢失

解决:拒绝客户端的写请求

哨兵集群的自动发现

通过 redis 的 pub/sub 系统实现的,每个哨兵都会往 __sentinel__:hello 这个 channel 里发送一个消息,内容是自己的 host、ip 和 runid 还有对这个 master 的监控配置,这时候所有其他哨兵都可以消费到这个消息,并感知到其他的哨兵的存在

哨兵配置

# sentinel.conf
port 26379
sentinel monitor mymaster 172.17.0.5 6379 2

这个配置代表需要监控127.0.0.1:6379这个主节点,2代表判断主节点失败至少需要2个Sentinel节点同意,mymaster是主节点的别名

# 启动哨兵
redis-sentinel sentinel.conf

哨兵的一些配置项:

# 如果超过了down-after-milliseconds配置的时间且没有有效的回复,则判定节点不可达
sentinel down-after-milliseconds <master-name> <times>
# 用来限制在一次故障转移之后,每次向新的主节点发起复制操作的从节点个数
sentinel parallel-syncs <master-name> <nums>
# slaveof no one一直失败(例如该从节点此时出现故障),当此过程超过failover-timeout时,则故障转移失败
sentinel failover-timeout <master-name> <times>
# 主节点通信密码
sentinel auth-pass <master-name> <password>
# 当一些警告级别的Sentinel事件发生(指重要事件,例如-sdown:客观下线、-odown:主观下线)时,会触发对应路径的脚本
sentinel notification-script <master-name> <script-path>
# 故障转移结束后,会触发对应路径的脚本
sentinel client-reconfig-script <master-name> <script-path>

动态调整配置:sentinel set 命令

监控多个主节点

sentinel monitor master-business-1 10.10.xx.1 6379 2
sentinel monitor master-business-2 10.16.xx.2 6380 2

屏幕截图 2020-10-07 161029

部署

运维

节点下线:

节点上线:

API

# 查看所有被监控的主节点状态以及相关的统计信息
sentinel masters
# 查看指定主节点
sentinel master <master name>
# 查看指定主节点的从节点
sentinel slaves <master name>
# 列出指定的主从集群sentinel节点(不包含本节点)
sentinel sentinels <master name>
# 返回指定的主节点地址和端口
sentinel get-master-addr-by-name <master name>
# 对符合<pattern>(通配符风格)主节点的配置进行重置
sentinel reset <pattern>
# 强制对集群进行故障转移
sentinel failover <master name>
# 检测当前可达的Sentinel节点总数是否达到<quorum>的个数
sentinel ckquorum <master name>
# 将Sentinel节点的配置强制刷到磁盘上
sentinel flushconfig
# 取消当前sentinel节点对指定master的监控那个
sentinel remove <master name>
# 监控指定master
sentinel monitor <master name> <ip> <port> <quorum>
# Sentinel节点之间用来交换对主节点是否下线的判断
sentinel is-master-down-by-addr

客户端连接

1)遍历Sentinel节点集合获取一个可用的Sentinel节点

2)通过sentinel get-master-addr-by-name master-name这个API来获取对应主节点的相关信息

3)验证当前获取的“主节点”是真正的主节点,这样做的是为了防止获取之后主节点又发生了变化

4)保持和Sentinel节点集合的“联系”,时刻获取关于主节点的相关“信息”

Java 客户端:

JedisSentinelPool pool =
    new JedisSentinelPool("mymaster", Set.of("192.168.1.101:26379","192.168.1.101:26380","192.168.1.101:26381"));
Jedis resource = pool.getResource();
System.out.println(resource.ping());
resource.close();