引入:
主从复制最大的问题还是在主节点上,主节点挂了,从节点就迷茫了,虽然能够提供读操作,但是从节点不能自动生成主节点,不能替换原有主节点对应的角色;此时,就需要程序员/运维手工的恢复主节点(redis哨兵:自动的对挂了的主节点进行替换)
从节点和主节点之间断开连接,有两种情况:
1.从节点主动和主节点断开连接:slaveof no one(这个时候从节点,就能够晋升成主节点)
注:这个意味着我们程序员主动修改Redis的组成结构
2.主节点挂了:这个时候,从节点不会晋升成主节点的,必须通过人工干预的方式,恢复主节点(这个是脱离我们掌控的,高可用下的一个典型问题)
注:
①这里有AOF文件,这个文件是Redis服务器启动的时候需要加载的
②Redis服务器需要按照可读可写的方式打开这个AOF文件,而这个文件对于root之外的用户只有读权限,因此serveice redis-server start启动的Redis服务器无法打开这个文件就启动失败(通过service redis-server start 启动的Redis服务器(主要是怕通过root启动Redis,权限太高,一旦Redis被黑客攻破,后果就比较严重)是通过一个Redis这样的用户来启动的)
③从节点是通过手动的方式运行的,此时root用户下启动Redis服务器,于是生成的AOF文件也就是root用户的文件
④当前这三个redis server用的是同一个AOF文件(本身就不填科学)
⑤之前配置文件里面没有改AOF文件的路径;改后变成
放在slave1和slave2文件夹中
这个问题的解决方案:把三个Redis服务器的生成文件,也区分开,更靠谱的是,直接把三个Redis服务器的工作目录区分开(修改配置文件中的dir选项)
1.停止之前的Redis服务器
2.删除之前工作目录下已经生成的AOF文件或者也可以通过chown命令修改AOF文件所属的用户
3.给从节点创建出新的目录,用来作为从节点的工作目录,并且修改从节点的配置文件,设定新的目录为工作目录
4.启动Redis服务器
注:
①人工不太靠谱,通过自动化的手段,来解决主节点挂了的问题
②哨兵机制,是通过独立的进程来体现的,和之前redis-server是不同的进程
③redis-sentinel不负责存储数据,致死对其他的redis-server进程起到监控的效果
④通常哨兵节点也会搞一个几个(多个哨兵节点构成,防止单哨兵节点挂了)
⑤实际开发中,对于服务器后端开发,监控程序,是非常重要的
⑥服务器,要求要有比较高的可用性,7*24运行,服务器长时间运行,总会有一些意外,具体什么时候出现意外,我们也不知道,同时也不能全靠人工来盯服务器运行
⑦写一个程序,用程序来盯着服务器的状态(监控程序和报警程序)
一.人工如何修复?
1.先看看主节点还能不能抢救,好不好抢救
2.如果主节点这边是啥原因挂的,不好定位;或者知道原因,但是短时间内难以解决,就需要挑选一个从节点,设置为新的主节点
1)把选中的从节点,通过slaveof no one ,自立山头
2)把其他的从节点,修改slaveof的主节点IP和port,连上新的主节点
3)告知客户端(修改客户端的配置),让客户端能够连接新的主节点,用来完成数据的修改的操作
4)当之前的挂了的主节点修好之后,就可以作为新的从节点,挂到这组机器中
二.哨兵机制(自动的处理)
单独的redis sentinel进程 提供了多个,并且这三个哨兵进程就会监控现有的redis master 和slave(监控:这些进程之间,会建立TCP长连接,通过这些长连接,定期发送心跳包)
借助这些监控机制,就可以及时发现,某个主机是否是挂了;如果是从节点挂了,其实没关系;
1.如果是主节点挂了,哨兵就要发挥作用了(此时一个哨兵节点发现主节点挂了还不够,hiatus需要多个哨兵节点来共同认同这件事情,主要是防止出现误判)
2.主节点确实挂了,这些哨兵节点就会推举出一个leader,由这个leader负责从现有的从节点,挑选一个作为新的主节点
3.挑选出新的主节点之后,哨兵节点,就会自动控制该被选中的节点,执行slaveof no one 并且控制其他从节点修改slaveof 到新的主节点上
4,哨兵节点会自动通知客户端程序,告知新的主节点是谁,并且后续客户端再进行写操作,就会针对新的主节点进行操作
哨兵节点的核心功能呢:1.监控 2.自动的故障转移 3.通知
注意:Redis哨兵节点,有一个,也是可以的
1.如果哨兵节点只有一个,它自身也是容易出现问题的,万一这个哨兵节点挂了,后续Redis节点也挂了,就无法自动恢复过程了
2.出现误判的概率也比较高:毕竟网络传输是容易出现抖动或者延迟或者丢包的,如果只有一个哨兵节点,出现上述问题之后,影响就比较大
使用docker来搭建环境:
原因:只有一个云服务器,就在一个云服务器上来搭建环境,需要6个节点,由于这些节点还挺多的,相互之间容易打架,依赖的端口号、配置文件,数据文件,如果直接部署,就需要小心的去避开这些冲突(类似于主从结构的配置)
但是如果用虚拟机,虚拟机比较吃配置,docker可以认为是一个"轻量级"的虚拟机,起到虚拟机这样隔离环境的效果,但是有没有吃很多的硬件资源
docker中的关键概念"容器",docker中的"镜像"(可以自己创建,也可以直接拿别人已经构建好的)和"容器"类似于"可执行程序"和"进程"的关系
1.安装docker和docker-compose
2.停止之前的Redis服务器
3.使用docker 获取到Redis镜像:docker pull redis :5.0.9
(docker pull 使用docker从中央仓库(默认就是从docker hub来拉取镜像))
拉取到的镜像,里面包含一个精简的Linux操作系统,并且上面会安装redis,直接基于这个镜像创建一个容器跑起来,此时,redis服务器就搭建好了(通过docker images命令来查看)
1.基于docker来搭建redis哨兵环境
2.docker-compose来进行容器编排(此处涉及到多个redis server也有多个redis哨兵节点,每一个redis server或者每一个redis哨兵节点都是作为一个单独的容器(6个容器))
3.通过一个配置文件,把具体要创建那些容器,每个容器运行的各种参数,描述清楚,后续通过一个简单的命令,就能过批量的启动/停止这些容器了(使用yml这样格式来作为配置文件)
1)创建三个容器作为redis的数据节点(一个主 两个从)
2)创建三个容器,作为redis的哨兵节点
注:其实这里也可以用一个yml文件,直接启动6个容器,如果把这6个容器同时启动,可能是哨兵节点先启动完成,数据节点后启动完成,哨兵节点可能就会先认为是数据节点挂了,虽然对大局不影响,但是可能会影响到观察日志的过程
第二个端口容器内部的端口,三个端口,每个容器内部的端口号都是自成一个小天地,容器1的6379和容器2的6379之间是不会有冲突的(可以把两个容器视为两个主机)
redis哨兵节点是单独的redis服务器进程
因为哨兵节点会在运行过程中,对配置文件进行自动修改,因此,就不能拿一个文件,给三个容器分别映射
、
这里启动哨兵节点,查看他的日志会出现
此时,这个哨兵节点不认识redis-master,redis-master相当于一个域名,docker会进行域名解析
docker-compose一下启动N个容器,此时N个容器都处于同一个"局域网中",可以使这N个容器之间相互访问
这里三个redis-server节点是一个局域网;三个哨兵节点是另一个局域网;默认情况下,这俩网络,不是互通的
解决方案:可以使用docker-compose把此处两组服务器放到同一个局域网中
用docker network ls列出当前docker中的局域网
此处先启动的三个redis server节点,就相当于自动创建了第一个局域网;再启动的后面的三个哨兵节点,就直接让这三个节点加到上面的局域网中,而不是自动创建新的局域网
通过这个操作就把哨兵节点和redis server节点放在统一个局域网中了
是否可以把六个容器,都写到同一个yml配置中,一次全都启动,不就直接解决了问题吗?
答:如果使用了这种方案,由于docker-compose启动容器的顺序不确定,就不能保证redis-server一定是在哨兵之前启动的,最终结果也能正确运行,但是执行的日志可能有变数;分成两组,就可以保证上述顺序,观察日志是比较可控的
odown
哨兵存在的意义,能够在redis主从结构出现问题的时候(比如主节点挂了,此时哨兵节点能够自动的帮我们重新选出一个主节点,代替之前挂了的节点,保证整个redis仍然是可用状态)
注:
①sdown主观下线,本哨兵节点,认为改主节点挂了
②odown:客观下线,好几个哨兵都认为该节点挂了,达成了一致(法定票数),此时主节点挂了这件事就石锤了
③此时就需要哨兵节点选出一个从节点,作为新的主节点,此处就需要提拔出一个新的主节点
哨兵重新选取主节点的流程:
1.主观下线:哨兵节点通过心跳包,判定redis服务器是否正常工作,,如果心跳包没有如约而至,就说明redis节点挂了
2.客观下线:多个哨兵都认为主节点挂了(认为挂了的哨兵节点数目达到了法定票数),哨兵们就认为这个主节点是客观下线
3.要让多个哨兵节点,选出一个leader,由这个leader负责选出一个从节点作为新的主节点
选出leader的过程
每个哨兵手里就只有一票,当哨兵1发现当前是客观下线后,就立即给自己投了一票,并且告述了2 3,
我负责这件事情,2 3反应慢了半拍才发现是客观下线;一看1乐意负责这件事情,立即投了赞成票(2 3当他们没有投出这个票的时候,收到拉票请求,就会投出去(如果有多个拉票请求,就会投给最先到达的))
如果总的票数超过了哨兵总数的一半,选举完成了(把哨兵个数设置成奇数个,就是为了方便投票)
4.此时leader选举完毕,leader就需要挑选一个从节点,作为新的主节点
1)优先级:每个redis数据节点,都会在配置文件中,有一个优先级设置,slave-priority,优先级高的从节点就会胜出
2)offset : 最大就胜出(offset从主节点这边同步数据进度数值越大,说明从节点数据和主节点数据就越接近)
3)runid :每个redis节点启动的时候随机生成一串数字(大小全凭缘分了)
把新的主节点指定好之后,leader就会控制这个节点,执行slaveof no one ,成为master;再控制其他节点执行slaveof ,让这些其他节点,以新的master作为主节点
注:
①哨兵节点不能只有⼀个.否则哨兵节点挂了也会影响系统可⽤性.
②哨兵节点最好是奇数个.⽅便选举leader,得票更容易超过半数.
③哨兵节点不负责存储数据.仍然是redis主从节点负责存储.
④哨兵+主从复制解决的问题是"提⾼可⽤性",不能解决"数据极端情况下写丢失"的问题.
⑤哨兵+主从复制不能提⾼数据的存储容量.当我们需要存的数据接近或者超过机器的物理内存,这样 的结构就难以胜任了.
为了能存储更多的数据,就引⼊了集群