这篇文章是对黄建宏第三部分的总结/学习笔记。redis
所谓的高可用,其实也就是这一部分介绍的几个点,即 复制 + 哨兵 + 集群。算法
目的
复制的目的是数据一致,就是从要达到和主的数据一致。服务器
流程
1.一开始,即初次
2.后面网络
一开始是发送同步命令,同步数据,数据达到一致。
后面是新的命令,主会把新的命令转发给从。数据结构
实现原理
两种方法,
1.数据法
2.命令法异步
1.旧版很低效
2.新版经过部分同步,解决低效socket
若是断线重连,旧版每次同步全部数据,而新版只同步掉线这段时间的数据。
并且同步数据很是耗时,咱们应该尽量的减小数据的复制,特别是避免每次复制全部数据,这样就能够避免每次复制了重复的数据。tcp
增量复制的细节
既然是增量复制,那么就要记录复制的进度。事实上,哪怕是全量复制,也有一个中介文件,即RDB文件。如今,增量复制,只是多了一个要记录进度的要求。学习
为何从断线重连主的时候,可能切换主?
就是有可能链接的不是同一个主,为何?线程
为何还要弄一个缓冲区? 服务器端已经有了偏移量,为何还要弄一个缓冲区?
为何还要缓冲区?
做用
用于主从链接的检测。
基于心跳检测实现的几个功能?
异常
复制的时候,可能出现两种异常
1.长时间掉线,由于宕机了
2.短期临时掉线,由于网络缘由
若是是长时间掉线,在重连以后,也能够复制掉线这段时间的全部命令。具体实现技术是,部分丢失命令重同步。
若是是短期临时掉线,由于网络缘由,那么这个时候只是某一个命令丢失,也能够针对这一个命令进行重发。具体实现技术是,1.客户端(从节点),发送心跳 2.服务器发送丢失的某个命令。
不论是哪种状况,长时间多命令,仍是短期临时的某一个命令,都是根据服务器端(主节点)缓冲区+偏移量来解决命令丢失而后重发的问题。
心跳自己的实现原理是什么?
首先,要理解的是,心跳的做用是什么,做用是:
1.是否能够通讯
2.通讯数据自己
至于具体的方式是什么还真不重要,只要能达到目的就可了:
1.ping
2.tcp socket
通常来讲,心跳不光光是检查是否能够通讯,并且要通讯数据,因此通常就不使用ping,并且tcp socket通讯。具体表现出来的形式是:
1.客户端发送数据
好比,redis的心跳包含,心跳命令名字 + 偏移量。
2.服务器接受数据
若是发现和客户端偏移量不同,就知道刚刚的那个命令丢失了,如今要重发,便可。
心跳时间间隔
1s。若是超过1s,即认为命令丢失,须要重发丢失命令。
先来一个图
首先,要明白一个大前提,那就是哨兵也是一个节点,只不过是一个没有数据的节点,那要它何用?监控数据节点。
哨兵节点之间互相通讯吗?通讯。 而RocketMQ监控节点之间是不通讯的,监控节点只与数据节点通讯。
还有一点,每一个哨兵节点是与全部数据节点保持通讯(即监控)。哨兵节点之间,也是每一个哨兵节点会与其余全部的哨兵节点通讯,由于升级数据节点为主的时候,会选择一个leader哨兵节点。
如何配置被监控的数据节点?
有两种方式,
1.一开始就在哨兵节点配置文件配置好,而后启动的时候,加载
2.或者,先启动哨兵节点,再启动主数据节点(配置好哨兵节点),注册到哨兵节点
不论是哪种方式,都是监控主节点,那从节点是怎么监控的呢?由于能够从主数据节点获取到从数据节点的信息,因此也就能够监控到从数据节点。
数据结构
哨兵节点和主数据节点创建链接,必须有两种链接:
1.命令
2.订阅hello
命令就是发送命令到主数据节点。
订阅hello是干吗的?订阅就是订阅主题,目的是实现哨兵节点之间的通讯。由于全部哨兵节点都订阅数据节点的同一个主题,若是有某一个哨兵节点发送数据到数据节点,那么全部哨兵节点都会收到订阅数据(包括发送数据的哨兵节点它本身也会收到,由于它也订阅了该数据节点的主题)。具体数据是1.输入数据是定时几秒发送命令2.输出数据是各个节点(哨兵节点和数据节点)的信息,好比,ip port之类的信息,若是这些信息有变动,那么就更新。
总结
哨兵和哨兵之间的通讯,与哨兵和数据节点的通讯是不一样的。
哨兵和数据节点是直接通讯,由于有配置ip port。
而哨兵如何其余哨兵,是由于每一个哨兵都监控了数据节点,而且都订阅了数据节点的同一个主题,因此,只要某一个哨兵发送数据到数据节点,其余哨兵就会收到这些信息,从而就知道了别的全部哨兵的存在了(包括ip port等信息数据)。因此,哨兵之间没有直接通讯,而是间接的经过数据节点的主题来通讯,因此也就不须要哨兵节点之间互相配置ip port。
哨兵与哨兵的第一次通讯,是经过数据节点的订阅主题间接的实现链接和通讯。完成第一次通讯以后,就获得了对方的信息,立刻还会互相双向建立命令链接,进行命令通讯,以便及时更新对方的信息。
注意
哨兵和数据节点之间,是有两种链接:1,订阅链接 2,命令链接。
而,哨兵之间,只有一种链接,那就是命令链接,由于订阅的是数据节点,哨兵之间不须要互相订阅。
订阅链接和命令链接的区别是什么?
首先,订阅链接的对象是,哨兵订阅数据节点,哨兵之间不会互相订阅;
命令链接的对象是,全部节点之间,包括哨兵/数据节点和哨兵/哨兵,注意主数据节点和主数据节点不通讯。
其次,做用,订阅链接的做用是,全部的哨兵节点都要订阅同一个数据节点的同一个主题,目的是能够自动发现别的哨兵,订阅链接算是第一次通讯,建立数据;而数据链接的做用是,用于后来定时更新数据。
哪些节点之间是有链接/通讯的?
1.哨兵和全部的节点(包括主和从)都有链接 再细分为两种,一种是哨兵和数据节点是订阅链接+命令链接,一直是哨兵之间只有命令链接没有订阅链接由于不须要订阅链接。
2.主和本身的从/多从 + 哨兵
3.从和本身的主且只有一个主 + 哨兵
还有,链接都是异步链接,什么是异步链接?
哨兵检测数据节点是否下线 两种方法
1.主观
2.客观
如何实现?基于命令链接。
主观就是我的认为的意思,在这里是当前这个哨兵认为,具体的判断算法是,一段时间内(几十秒),一直收不到命令链接(ping命令)的响应(数据节点会组装响应数据),那么就认为数据节点下线。
而客观是,数据节点真的已经下线,什么叫真的,就是不少哨兵都检测到数据节点确实已经链接不上了,那么就认为该数据节点真的挂了。具体算法是: 1.哨兵1检测到数据节点挂了
2.哨兵1询问其余的哨兵节点是否真的挂了
3.其余哨兵节点都一致认为数据节点确实挂了
4.哨兵1就把数据节点状态置位下线
5.其余哨兵也是同理处理
至于什么叫一致认为,这个数字可配置,规定是几个,就是几个,并且每一个哨兵规定的可能不同,总之,只要最终计算获得的数量大于这个值,那么就认为是客观下线。
就算是主观下线,一段时间内,这个时间也是可配置,不一样哨兵可能配置的值也不同。
总结
虽然下线有两种,可是判断一个数据节点是否下线的标志是,主观和客观都要知足。主观是单个哨兵认为下线,并记录下线信息,客观是配置数量的哨兵互相通讯获得对方的下线信息,而后计算数量,最终才确认下线。
下线以后,怎么办?选择新的主数据节点。具体步骤是:
1.哨兵之间先选一个leader哨兵
2.leader哨兵实现故障转移,说是故障转移,其实就是升级其中的某一个从数据节点为主,降级主数据节点为新的主节点的从
选leader哨兵的算法?
1.输入数据
包含字段:
1)是否下线 //0未下线,1下线
2)是检测是否下线仍是选leader //*检测是否下线,当前哨兵runId就是选leader
3)计数 //一开始是0
说明
因为选leader的命令和检测是否下线的命令是同一个命令,只是有个参数不一样,用于标识当前命令是选Leade仍是检测是否下线。
2.输出数据
包含字段:
1)是否下线 //0未下线,1下线
2)是检测是否下线仍是选leader //*检测是否下线,当前哨兵runId就是选leader
3)计数 //若是赞成,每次加1
关于计数
举个例子
1.哨兵1申请哨兵2,成功,加1
2.哨兵1申请哨兵3,成功,再加1
3.哨兵1的计数如今是2,过半,成为leader
注:什么纪元不纪元,其实就是计算数量。每次申请别人是否赞成本身成为leader,若是赞成,这个字段的值就加1,最终总数超过一半的哨兵,那么就是leader。由于申请的时候,有前后顺便,谁最早过半,谁就是leader。
选从数据节点的算法?
按如下几项的前后顺序,依次进行排序,最终获得一个从数据节点。
1.是否下线
2.优先级
3.偏移量 4.服务器id
细节以下
首先,获得全部的节点的集合。
是否下线指,1.过滤已经下线的(客观下线)2.过滤几秒以内没有响应的(主观下线)3.过滤几毫秒以内没有响应的(临时网络问题),总之,就是过滤掉下线或网络通讯很差的。
剩下的,再按优先级排序。优先级是指?全部的任何一个优先级,都是一个值为数字的字段,好比线程优先级,或者应用程序里常常会使用到的优先级。
偏移量最大,说明数据最新。
最后,服务器id排序。
完成,选出一个从数据节点。
节点之间通讯的几种不一样类型?
1.订阅链接
2.命令链接
3.info命令
4.ping
前面两种是链接,命令包括设置这样的操做,好比设置从为主(slaveof no one)。 info和ping是为了获取状态信息,便是否通讯正常等。
但凡是涉及到监控通讯状态是否正常的,基本上都是几秒一次。
slaveof no one,表示设置为主,slaveof ip port,表示设置为ip/port的从,slaveof 参数,这个命令是由哨兵发出的。
步骤
1.先选择一个哨兵leader
2.再选择一个从节点进行升级
这里面最重要的是如何选择,即选择的算法是什么。
黄建宏