redis的sentinel模式

介绍

  • Redis Sentinel 是一个分布式系统,用于管理多个 Redis 服务器(instance),本质上只是一个运行在特殊模式下的 Redis 服务器,提供高可用性(HA)解决方案

Sentinel

  • 监控: Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
  • 提醒: 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
  • 自动故障迁移: 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

消息丢失

  • Redis 主从采用异步复制
  • Sentinel 无法保证消息完全不丢失,可以通过限制主从延迟过大,尽可能保证消息少丢失。
1
2
min-slaves-to-write 1
min-slaves-max-lag 10

第一个参数表示主节点必须至少有一个从节点在进行正常复制,否则就停止对外写服务,丧失可用性。

第二个参数单位是秒,表示如果 10s 没有收到从节点的反馈,就意味着从节点同步不正常,要么网络断开了,要么一直没有给反馈。

Sentinel作为服务器的命令表

1
2
3
4
5
6
7
8
9
struct redisCommand sentinelcmds[] = {
{"ping",pingCommand,1,"",0,NULL,0,0,0,0,0},
{"sentinel",sentinelCommand,-2,"",0,NULL,0,0,0,0,0},
{"subscribe",subscribeCommand,-2,"",0,NULL,0,0,0,0,0},
{"unsubscribe",unsubscribeCommand,-1,"",0,NULL,0,0,0,0,0},
{"psubscribe",psubscribeCommand,-2,"",0,NULL,0,0,0,0,0},
{"punsubscribe",punsubscribeCommand,-1,"",0,NULL,0,0,0,0,0},
{"info",sentinelInfoCommand,-1,"",0,NULL,0,0,0,0,0}
};

自动发现

当Sentinel发现主服务器有新的从服务器出现时,Sentinel除了会为这个新的从服务器创建相应的实例结构之外,Sentinel还会创建连接到从服务器的命令连接和订阅服务

无需设置sentinel对应其他sentinel的地址,通过发布,订阅功能来自动发现正在监视相同主服务器的其他sentinel,这一功能是通过想频道 sentinel:hello发送信息来实现的。

  • 默认情况下,Sentinel会以每两秒一次的频率,通过命令连接向所有被监视的主服务器和从服务器发送命令,包含sentinel的ip,端口,pid

  • 每个sentinel都会订阅被他监视服务的 sentinel:hello频道,如果有新的sentinel加入,更新自己的sentinel列表

  • 对于监视同一个服务器的多个Sentinel来说,一个Sentinel发送的信息会被其它Sentinel
    接收到,用于更新自己的sentinel列表

  • 添加新的sentinel时,先检查列表中是否已存在相同id或者相同地址的sentinel,如有,先移除

  • Sentinel之间不会创建订阅连接

主观/客观下线状态检查

  • 主观下线(SDOWN)指的是单个 Sentinel 实例对服务器做出的下线判断。
  • 客观下线(ODOWN)指的是多个 Sentinel 实例在对同一个服务器做出 SDOWN 判断, 并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服务器下线判断。

服务器对 PING 命令的有效回复包含:

  • +PONG
  • -LOADING
  • -MASTERDOWN

对于主服务器:主观下线状态切换到客观下线状态,使用Gossip协议,在sentinel给定的时间内,从sentinel收集到了足够数量的主服务器下线报告,状态改成客观下线。

客观下线只适合主服务器。

其他类型的redis实例,sentinel判断下线无需协商。

每个 Sentinel 都需要定期执行的任务
  • 每个 Sentinel 以每秒钟一次的频率向它所知的主从服务器以及其他 Sentinel 实例发送一个 PING 命令。
  • 如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 那么这个实例会被 Sentinel 标记为主观下线。
  • 如果一个主服务器被标记为主观下线, 那么正在监视这个主服务器的所有 Sentinel 要以每秒一次的频率确认主服务器的确进入了主观下线状态。
  • 如果一个主服务器被标记为主观下线, 并且有足够数量的 Sentinel (配置文件指定的数量)在指定的时间范围内同意这一判断, 那么这个主服务器被标记为客观下线。
  • 主服务器被 Sentinel 标记为客观下线时, Sentinel 向下线主服务器的所有从服务器发送 INFO 命令的频率会从 10 秒一次改为每秒一次。
  • 当没有足够数量的 Sentinel 同意主服务器已经下线, 主服务器的客观下线状态就会被移除。 当主服务器重新向 Sentinel 的 PING 命令返回有效回复时, 主服务器的主管下线状态就会被移除。

故障转移

  • 在已下线主服务器的所有从服务器里面,挑选出一个从服务器,并将其转换为
    主服务器。
  • 让已下线主服务器属下的所有从服务器改为复制新的主服务器
  • 将已下线主服务器设置为新的主服务器的从服务器,当这个旧的主服务器重新上线时,它就会
    成为新的主服务器的从服务器
新的主服务器是怎么挑选出来的

领头Sentinel会将已下线主服务器的所有从服务器保存到一个列表里面

  • 删除处于下线或者断线状态的从服务器
  • 删除最近 5s 内没有回复过领头Sentinel的INFO命令的从服务器
  • 删除与已下线主服务器连接断开超过down-after-milliseconds * 10 ms 的从服务器
  • 剩下的,选择优先级最高、复制偏移量最大的从服务器,如果复制偏移量不可用,选择运行ID最小的从服务器升级为主服务器

参考:https://redis.cn/topics/sentinel.html
《redis设计与实现(第二版)》

------本文结束感谢阅读------
显示评论
0%