前言

基于哨兵机制,实现高可用,也就是集群架构。

主数据节点挂了

依次执行以下步骤
哨兵节点监控数据节点
1.所有从数据节点监控挂了,然后,中止复制主数据节点
2.所有哨兵节点监控挂了,然后,判断是否超过下线时长
3.如果超过下线时长,那么leader哨兵节点将会进行故障转移

leader哨兵节点晋升新的主节点
4.所有哨兵节点之后,互相选举leader哨兵节点
5.leader哨兵节点,根据一些条件选择一个从数据节点,晋升它为主数据节点
6.leader哨兵节点,通知下线主数据节点的所有从节点,成为新的主数据节点的从节点,并且从新的主数据节点复制数据
7.leader哨兵节点,监控下线主数据节点,一旦重新上线,就让它降级成为新的主数据节点的从节点,并且从新的主数据节点复制数据

所有哨兵节点如何选举leader哨兵节点?

leader哨兵节点,是根据什么条件,来选择晋升哪个从数据节点为新的主数据节点?

每个哨兵节点如何监控所有的数据节点?

首先,可以肯定的是,每个哨兵节点都会监控所有的数据节点。

具体步骤
1.一开始是监控启动哨兵节点时指定的所有的已有的主数据节点集合
2.后面,会和其他哨兵节点通信,获取对方的监控的其他的所有主数据节点集合
3.这样,每个哨兵节点都监控所有的主数据节点和从数据节点(根据监控主数据节点,就可以获取到主数据节点的所有从数据节点)

哨兵和数据节点的区别?

运行模式不一样
就是启动的时候,初始化时的运行模式不一样
1.数据节点是普通的redis服务器
2.哨兵节点也是redis服务器,只不过运行模式不一样,即只监控没有数据


命令
1.哨兵启动时,无需加载持久化数据文件恢复持久化数据,因为它根本就没有数据
2.启动后,哨兵没有读写数据的命令

Redis服务器的生命周期

1.启动 初始化,加载持久化数据文件,恢复持久化数据到内存
2.从配置文件,加载命令集合
允许客户端执行哪些命令
1)数据节点
2)哨兵节点
非数据命令
3.
4.

哨兵节点的初始化状态-数据结构

监控哪些主数据节点

数据结构是Map<节点名字,服务器数据结构>

主观下线和客观下线

哨兵监控的主数据节点集合

1.哨兵的配置文件,指定在哪个端口(port)监控哪个主数据节点(主数据节点名字)
如果是启动数据结点,那么就是在数据节点的配置文件,指定哨兵的IP/port
2.启动 初始化加载

哨兵节点的专用代码

其实就是配置文件有点不一样,比如,命令集合配置文件等等。

哨兵节点和主数据节点建立连接

步骤
1.配置文件指定了主数据节点集合
2.哨兵节点一个个地,根据主数据节点集合,和主数据节点建立连接
创建连接之后,哨兵节点就成了主数据节点的客户端


连接有两种/两个
1.命令连接
2.订阅连接
订阅连接,指的是哨兵节点订阅主数据节点的主题(哨兵-hello主题)。

这两个连接,都是异步连接。

订阅连接-实现原理

与普通的消息队列的区别?
1.消息队列
生产者——中间件——消费者
2.redis-哨兵节点订阅主数据节点的主题
哨兵节点——主数据节点(主题数据存储在主数据节点,并没有第三方中间件)


订阅连接,就是所有的哨兵节点——所有的主数据节点,两两都会发生订阅关系。
订单连接,主要是想从主数据节点得到什么数据呢?
1.哨兵节点发送数据到主题
某个哨兵节点向主数据节点发送命令连接-publich
发送数据如下,1.哨兵节点信息2.主数据节点信息
2.主数据节点,发送主题到所有监控的哨兵节点(包括发送数据的哨兵节点自己也会接受主题数据)
接受主题数据的哨兵节点,判断:
如果是自己发送的数据,那么丢弃该主题数据;
如果是别的哨兵节点发送的数据(即不是自己发送出去的数据),那么更新哨兵节点数据+主数据节点数据/从数据节点数据。

命令连接-实现原理

命令连接主要是想得到什么数据呢?
得到主数据节点的所有从数据节点,然后与所有从数据节点建立连接,从而监控了所有从数据节点。 这个是通过info命令,得到的响应。
响应内容的具体格式就是
1.主数据节点的ip/port 2.从数据节点的ip/port

得到数据之后,哨兵节点每次都会更新自己的主数据节点集合里的数据字段。

数据结构如下
哨兵节点——主数据节点——从数据节点 //可以看到,数据结构是根据数据结构和指针,一层一层地指向其他相关数据结构。


命令连接和订阅连接的区别,到底何在?


命令发送间隔时间?
1.命令连接
比如,info是10s
2.订阅连接
2s

主数据节点的run_id

1.启动时,运行时生成
2.每次启动,会改变,即run_id值不一样
哨兵节点,是通过命令连接info,得到主数据节点的响应;得到主数据节点的run_id字段之后,会更新哨兵节点保存的主数据节点集合里的对应run_id字段的值。

从数据节点

哨兵节点,和主数据节点一样,也会和从数据节点建立连接
1.命令连接
2.订阅连接


哨兵节点,得到的响应内容?
1.从数据节点的run_id
2.从数据节点所属于的主数据节点的ip/port
3.其他重要字段
复制偏移量等等

反正,所有需要的数据字段,都是保存在对应的数据结构里。

数据结构-哨兵节点和数据节点的数据结构的区别?

主要是包含了哪些核心字段的区别。

数据结构-指向关系?

哨兵节点——主数据节点——1.从数据节点2.哨兵节点

解释:
1.哨兵节点——主数据节点
是表示哨兵节点监控了哪些主数据节点。
2.主数据节点——1.从数据节点2.哨兵节点
是表示,1.哪些从数据节点属于该主数据节点2.该主数据节点被哪些哨兵节点监控。
每次互相通信之后,被哪些监控的哨兵节点数量+1,直到被哪些监控的哨兵节点达到最大值。或者,等到有新的哨兵节点加入,再次+1。

命令连接和订阅连接的区别?

1.哨兵节点和数据节点,既有命令连接和订阅连接
命令连接:作用是哨兵节点和主/从数据节点互相通信
订阅连接:作用是哨兵节点用来发现其他哨兵节点
2.哨兵节点和哨兵节点,只有命令连接,没有订阅连接
因为订阅连接主要是用于哨兵节点通过订阅主数据节点的主题,来发现其他哨兵节点。

哨兵节点之间互相通信只需要命令连接!——而且两两之间会互相创建命令连接,即A——B并且B——A,总共两个命令连接。命令连接-哨兵节点之间

作用是监控主数据节点的下线
1.主观下线
2.客观下线


数量
1.首先,从数量来说,就是主观只有一个人,自己认为,这叫主观。就是当前哨兵节点觉得主数据节点下线了,那么这就是主观下线。
2.如何,客观,就是半数以上的哨兵节点认为确实下线了,那么就是客观下线。


具体判断下线细节?
哨兵节点向所有节点,发送命令-ping。每秒发送一次。
1.所有主数据节点
2.所有从数据节点
3.所有其他哨兵节点 哨兵节点之间,两两分别互相发送命令ping。


如果下线
哨兵节点,设置那个节点的状态字段为下线。


下线时间
1.如果每个哨兵节点的下线时间大小一样,比如都是1分钟,被监控的节点一直没有回应命令ping,那么1分钟之后,就可以确认下线节点。
2.如果每个哨兵节点的下线时间大小不一样,比如有的是1分钟,有的是2分钟,那么需要2分钟之后,才能确认下线节点。
因为需要过半的节点都认为下线,才是真正的下线。

主观下线

客观下线

实现步骤,三部曲(即三个步骤)
1.向其他哨兵节点,发送命令-下线询问命令(即setinal下线命令)
下线命令的格式:setinal 下线命令 主节点数据ip/port
2.其他哨兵节点接受下线询问命令,并且响应数据给哨兵节点
响应数据格式:1.是否下线 2.leader_runid 3.leader_纪元
3.计算下线数量,如果大于当前哨兵节点设置的客观下线数量,那么就把那个主数据节点的下线状态字段设置下线状态


选举leader哨兵

配置纪元(leader哨兵节点计数器)

有几种
1.哨兵节点本身的计数器 哨兵节点本身的数据结构里,包含了计数器字段。

值来自哪里?每次向其他哨兵节点发送命令-下线询问命令的时候,得到的响应数据-计数器字段,会加1。也就是说,响应数据-计数器字段+1之后的值,会覆盖旧的值。

2.下线询问命令sentinal的响应字段-计数器
1)下线状态

2)leader_runid
第一个最先下线询问的哨兵节点被设置为leader,也就是说,leader_runid的值是第一个哨兵节点的runid。

后面下线询问的哨兵节点,全部被拒绝,被拒绝的意思是说,一旦runid已经被设置为第一个询问的哨兵节点,后面再询问,得到的值是*,即不同意你成为leader。

3)leader_纪元(leader计数器) 值来自哪里?1.初始值来自发送询问命令的哨兵节点的计数器字段(sentinal 下线命令里包含了计数器字段)2.如果同意发送哨兵节点为leader,那么就把这个值加1,然后作为响应数据给到发送哨兵节点——哨兵节点再把这个值覆盖旧的值。


计数器加1
上面的加1,描述有点问题,正确的应该是下面这样。

是在哪里加1?由谁来加1?答案是发送命令的哨兵节点。关于计数器加1,具体细节和步骤如下:
1.源(即发送)哨兵节点发送下线询问命令
包含了计数器字段

2.目标(即接受)哨兵节点接受询问命令
如果同意源哨兵节点为leader,那么就把响应数据-第三个字段(即计数器字段),设置为源哨兵节点的计数器的值。

3.源哨兵节点接受响应
分以下几步
1)判断响应数据-计数器字段的值是否和自己的计数器相等
2)如果相等,继续判断响应数据-runid字段的值是否是自己的runid
3)如果相等,那么计数器加1即可。

这就是计数的流程。

最终数量过半者,即为leader。

故障转移

步骤如下
1.根据一定的条件,选择一个合适的从数据节点
2.晋升从数据节点为新的主数据节点
3.让其他从数据节点复制新的主数据节点
4.旧的主数据节点,一旦上线,降级为从数据节点,并且复制新的主数据节点

命令-ping:具体实现?

没看源码,估计应该就是普通的命令,只不过名字叫做ping命令,其实和我们常说的命令行ping ip应该没有什么关系。

主要关注的是,该命令的作用是什么?就是检查是否通信正常。

至于,是命令行的ping命令,还是普通的ping命令,不重要。