Sentinel是 Redis 版本 2.8 后推出的一种高可用性的解决方案,也是一种集群部署方式。用来解决Redis主从模式下的高可用切换问题。而 Redis-Cluster 是 3.0 版后推出的 Redis 分布式集群解决方案,集群通过分片来进行数据共享,并提供复制和故障转移功能。
好了,本篇基本介绍完毕。
Sentinel
它用来监视主从服务器的,一般是至少3个或以上的奇数个Sentinel来监视一套主从服务器,下面说一下它的功能。
01.启动并初始化Sentinel
初始化服务器:Sentinel本质只是一个运行在特殊模式下的Redis服务器,和单机redis服务器处理的步骤相似,但是也不少区别。
因为功能不是处理命令什么的,是去监控redis服务器,所以不会去服务器还原数据库,就不会加载rdb或aof文件。另外该服务器也不会去执行数据库操作命令、事务命令、持久化命令等。但是复制命令、发布订阅、事件处理还是有的。
加载Sentinel专用代码:一般redis普通服务器是去加载redis.h或redis.c的代码,但是Seentinel则使用sentinel.c代码。包含服务器默认端口号、服务器命令表。通过sentinelcmds命令表可知Sentinel可以执行客户端那些命令,不能执行那些命令。
初始化Sentinel状态的master属性:Sentinel状态的masters字典记录了所有被Sentinel监视的主服务器的信息。字典的键是主服务器名,值为其他结构。
typedef struct sentinelRedisInstance { //... //实例地址 sentinelAddr *addr; //...}sentinelRedisInstance;
上面addr是一个新结构,里面只记录了主服务器的ip和port两个信息。Sentinel初始化引发master字典初始化,而该字典初始化是根据被载入的Sentinel配置文件来进行的。
创建连向主服务器的网络连接:初始化Sentinel最后一步是创建和被监视主服务器之间的网络连接。Sentinel将成为主服务器的客户端。Sentinel会创建两个连向主服务器的异步网络连接,一个是命令连接,另一个是订阅连接。订阅连接是防止客户端不在线没收到消息。命令连接就是给Sentinel向主服务器发消息用的。
02.获取主从服务器信息
Sentinel每隔10s统一向主从服务器发送info命令获取他们信息来更新Sentinel对它们的认知,这样主从服务器有什么变化(主掉线,新增从)Sentinel可以知道并做出相应反馈(记录、选举)。
获取主服务器信息:命令连接创建之后,Sentinel默认每10s发info命令给主服务器获取信息。信息是主服务器自身信息(运行id和role域记录信息)和它的所属从服务器信息。然后Sentinel将获取的信息用来更新自己记录的对主服务器的认识,以及更新它所属的从服务器是否有变化,新增从就记录,从下线就删除记录。
获取从服务器信息:命令连接创建之后,Sentinel默认每10s发info命令给从服务器来获取信息。信息包括从服务器运行id、role、所属主的ip和port、主从连接状态,从优先级,从复制偏移量。
03.__sentinel__:hello频道
向主从服务器发送信息:Sentinel每隔2s通过命令连接给被它监视的主和从服务器发一个命令,信息内容是Sentinel一些自身信息和被监视的服务器自身信息。通过命令连接向__sentinel__:helle频道发送Sentinel自己记录的信息。用于给订阅该频道的其他Sentinel更新信息。
接收主从服务器频道信息
订阅频道接收信息:
当Sentinel与任意服务器建立起订阅连接之后,Sentinel会通过__sentinel__:helle频道接收信息。接收其他Sentinel通过命令连接给该频道发送它们自己记录的信息。因为一个主或从服务器不一定是由一个Sentinel来监视,可能是多个Sentinel来监视。
更新sentinels字典:
因为有多个Sentinel监视同一个服务器,所以当前的Sentinel需要记录其他和自己干的一样活的Sentinel。
typedef struct sentinelRedisInstance { //... //sentinels字典,记录其他Sentinel信息 //...}sentinelRedisInstance;
一个Sentinel通过分析接收频道信息得知其他Sentinel存在,并通过发送频道信息告知其他Sentinel自己的存在,用户在使用Sentinel不用提供各个Sentinel地址信息,只要监视同一个主服务器的多个Sentinel可自动发现对方。
创建连向其他Sentinel的命令连接:
和其他Sentinel只创建命令连接,不创建订阅连接,因为是通过接收频道信息发现未知Sentinel,所以只要和主从服务器建立订阅连接即可。和已知Sentinel只要用命令连接来进行通信就足够了。
04.主客观下线
主观下线:Sentinel每隔一秒发一个ping命令给和它创建命令连接的实例(主、从、其他Sentinel),看实例返回的ping命令回复来判断是否在线。
针对无效回复,Sentinel配置文件有个时间限制,会当在规定时间内连续向Sentinel返回无效回复时,Sentinel则认为该实例进入自己认为的主观下线状态。然后在自己的masters字典中找到该实例结构的flags,设置为SRI_S_DOWN标识。
当多个Sentinel设置的主观下线时长不同时,有的Sentinel认为主观下线了,有的还在等待判断,超过时间限制也判为主观下线。
客观下线
发送命令:
sentinel is-master-down-by-addr... 发送命令询问其他Sentinel是否同意主服务器已下线。
接收命令:
当Sentinel接收到其他Sentinel发送的is-master-down-by-addr命令时,根据里面的参数提供的主服务器信息来查看自己是否已对该服务器标志主观下线。然后返回自己记录主服务标志等信息给原Sentinel。
接收回复:
当接收到其他Sentinel反馈is-master-down-by-addr命令的回复时,如果也是主观下线。并且某一个Sentinel收集的数量达到配置条件时,则将服务器的flags属性的SRI_O_DOWN标识打开,表示主服务器进入客观下线状态。
当然,每个Sentinel的配置条件不同,A收集到2个时就认为主服务器客观下线,可能B要收集5个才行。
05.选举领头Sentinel
1、所以在线的Sentinel都有机会当选领头Sentinel;
2、每个发现主服务器进入客观下线时,都会要求其他Sentinel将自己设置为局部领头Sentinel;
3、在判断客观下线时会发送is-master-down-by-addr命令,里面有个参数runid是设置为*,但是现在已经知道客观下线了,参数就是发送该命令的Sentinel服务器的运行id,要求收到该命令的把发送者设置为局部领头,并且后面会拒绝其他Sentinel设置;
4、局部领头先到先得,因为判断客观下线时设置条件不一样,有的Sentinel先标识客观下线;
5、当某个局部领头有半数的Sentinel支持,它就称为领头Sentinel,规定时间没有符合该条件将重新选举一次,直到选出来为止。
06.故障转移
选择新的主服务器:领头Sentinel会选择已下线的主服务器所属的从服务器中选一个当新的主服务器,会以优先级高、复制偏移量最大、运行id最小的从服务器来当主服务器。然后Sentinel给这个从服务器发送slaveof no one命令转成主服务器。
修改剩余从服务器复制目标:领头Sentinel会对剩余的从服务器发送slaveof命令,让它们把复制目标变成刚上任的主服务器。
监视旧主服务器:最后领头Sentinel监视已下线的主服务器,如果上线,就把它设置为刚上任的主服务器的从服务器。
Cluster
集群知识点信息较多,已在脑图中记录了。
https://www.processon.com/mindmap/5eb50b57e401fd16f423808c
以上都是学习《Redis设计与实现》记录的,为什么记录呢,?因为看一遍可能不会把书中所有知识点完全吃透或连串起来,在写脑图时可以简单复习一遍并用自己语言去理解和记录,再看第二遍会有新的认识和理解。
金狮面狨
金狮面狨,也叫金狨,头体长为25-33厘米,尾长32-40厘米,体重400-800克,是狨类中体形最大的。体毛为金黄色。脸部周围的毛较长较深,呈鬃毛的形状。四肢细长,因锋利的爪子,擅长攀爬和跳跃。尾巴和爪子显黑色。牙齿共有32枚,下颚上长有长长的“獠牙”,门齿与犬齿的长度几乎相等。。
栖息于热带原始森林,通常活跃于离地面3-10米高的大树中层和冠层,以浓密的藤蔓和其他寄生植物等为掩护,在交织的枝杈间栖息。觅食各种昆虫、蜘蛛、蛾、蝇、蛴螬、蠕虫,以及各种植物的嫩芽、花朵和果实等,尤其喜欢吃无花果。原产于巴西的大西洋沿岸地区。为濒危动物,野生金狮面狨大约还有1000只,圈养数量为500只。保护组织正在采取各种措施防止金狮面狨的绝种。
列入《世界自然保护联盟濒危物种红色名录》(IUCN) 2008年 ver 3.1——濒危(EN)。