Redis主从复制与哨兵机制

Redis主从复制与哨兵机制

一、主从复制

在了解哨兵机制前先来了解一下主从复制。在实际的应用过程中常常会遇到一些高并发高数据量的场景,对缓存提出了高可用性高稳定的需求,然而在只有单个redis服务器时,单台redis服务器需要处理所有的请求负载,压力大,容错性低,一旦出现故障会导致所有请求被送到持久层数据库。此外,单个Redis虽然容量为256G,但并不能将所有内容都用作Redis存储内存,一般情况下单台Redis最大使用的内存不应超过20G。对此解决办法是使用多台Redis服务器。

1、什么是主从复制

主从复制即将多台Redis服务器分为一台主服务器(master)和多台从服务器(slave),其中主服务器负责写操作,从服务器负责读操作,主服务器会定期将数据同步到从服务器中保证数据的一致性。

在这里插入图片描述

2、同步的两种方式

2.1、全量同步

即将主服务器中的全部数据都发送给从服务器,是一个非常重型的操作,当数据量很大时会对主从节点和网络造成很呆的开销。通常应用于初始化slave或其他无法进行增量同步的情况。

全量同步的过程:

  • 从服务器连接主服务器,发送SYNC命令

  • 主服务器收到命令后开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有命令

  • 主服务器执行完层BGSAVE后,向从数据库发送快照文件,并在发送期间继续记录被执行的命令

  • 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照文件

  • 从服务器完成对快照的载入,开始接受命令请求,并执行来自主服务器的缓冲区的写命令

在这里插入图片描述

2.2、增量同步

增量同步是指slave初始化后开始正常工作时主服务器发生写操作时同步到从服务器的过程。通常情况下主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接受并执行

3、主从复制的实现

首先拷贝一份配置文件作为从服务器的配置文件

在这里插入图片描述

然后更改配置文件,更改port属性,可以改成6380

在这里插入图片描述
添加slaveof配置,说明该从服务器对应的主服务器的IP和port,当然这句话也可以放在启动时在命令行中输入

在这里插入图片描述

启动后可以通过info replication命令查看从服务器的状态以及所属服务器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R5nK8jMB-1592309310736)(C:\Users\13719\AppData\Roaming\Typora\typora-user-images\image-20200614221305999.png)]

可以看到在从服务器想要写入数据是失败的

在这里插入图片描述

二、哨兵机制

虽然主从复制可以很好的解决高并发高性能的需求,但仍然存在这样一个问题:如果Master出现问题怎么办?出于这样的原因引入了哨兵机制

1、什么是哨兵

什么哨兵呢?在现实生活我们常常能在军营门口看到哨兵,哨兵的任务是站岗,监测大门口的状况,及时发现异常状况,redis中的哨兵也同样肩负着这样的职责。

哨兵(Sentinel)是一个独立的进程,其通过发送命令等待redis服务器响应,从而监控各个Redis服务器的状态,并在master出现故障时切换新的master。在一个架构中可以使用多个哨兵进程

在这里插入图片描述

2、哨兵的作用

2.1、监控

哨兵会不断的检查Master和Slave是否运行正常.

2.2、提醒

当被监控的某个redis节点出现问题时,哨兵可以通过API向管理员或其他应用程序发送通知

2.3、故障转移

当一个主服务器被哨兵视为客观下线时,该哨兵会和其他哨兵协商选出领头哨兵进行故障转移工作。

3、哨兵的定时任务

  • 哨兵每10秒会向它所知的所有主服务器和从服务器发送INFO命令以发现从节点,并确认节点之间的主从关系
  • 每个哨兵每2秒会通过订阅发布机制,通过master节点的_sentinel_:hello频道交换信息
  • 每个哨兵每秒会对其他哨兵以redis节点执行ping命令,以确认节点是否正常运行

4、哨兵间的自动发现

在一个集群中的哨兵之间是知到互相的存在的,但在配置哨兵的配置文件时,只需要配置哨兵需要监控的主节点的信息即可,而不用配置其他哨兵的信息。这是因为哨兵之间会通过订阅发布机制来进行自动发现。

每个哨兵都会订阅它所监控的主服务器和从服务器的_sentinel_:hello频道,哨兵会以每两秒一次的频率向该频道中发送一条信息,包含了哨兵的ip地址、端口和运行ID。当一个哨兵发现了一个新的哨兵发出的消息时,它会检验维护已知哨兵的列表中是否存在拥有相同运行ID或相同地址的哨兵,若有,则该哨兵会先移除列表中已有的相同运行ID或相同地址的哨兵,然后添加新的哨兵,若没有则直接将新的哨兵添加到已知Sentinel的列表中。

此外哨兵发送的消息中还包含完整的主服务器的配置信息,若一个哨兵的主服务器配置信息旧于另一个哨兵发送的配置信息,那么该哨兵会升级到新的配置。

5、主观下线与客观下线

哨兵会以每秒一次的频率向集群中的主服务器和从服务器发送ping命令,若在down-after-milliseseconds时间内ping连接无效,则将该服务器视为主观下线(主观下线即单个哨兵节点对redis节点视为下线)之后该哨兵节点会询问其他一同监控同一主服务器的哨兵节点是否也将该服务器视为主观下线,若判定该服务器为主观下线的哨兵节点数量超过了quorum后将会视其为客观下线。

6、故障转移

(这一块不是很详细,深入理解后再重新整理)

6.1、选举领头Sentinel

当集群中主节点被认为客观下线时,需要在Sentinel中选举出Leader,由它来负责故障转移工作。当故障转移工作完成后所有Sentinel又会恢复到平等的地位。

选举流程:

(1)若某个Sentinel认定master客观下线,该Sentinel会先查看自己有没有投过票,若自己已经投票给其他Sentinel了,则在两倍故障转移的超时时间自己就不会 称为Leader,即它已经成为了Follower

(2)若该Sentinel还没有投过票,它就会成为Candidate

(3)成为Candidate后会向其他节点发送is-master-down-by-addr命令请求投票

(4)收到is-master-down-by-addr命令的Sentinel会检查自己是否已经投票,若已经投过票,则不再参与投票,若没有参与投票,则将票投给发送该命令的Candidate

(5)Candidate会不断统计自己的票数,若认同该Candidate成为Leader的票数超过一半且超过配置文件中设置的quorum,则该Sentinel成为Leader

(6)若在一个选举时间内,Candidate没有获得超过一半且超过quorum的票数,则竞选失败

(7)若在一个选举时间内,没有一个Candidate获得更多的票数,则等待超过两倍故障转移时间后重新投票

6.2、故障转移

在选举出Leader后,Leader就会对已下线的主服务器进行故障转移操作。Leader会咋子已下线的主服务器中的所有从服务器中挑选出一个从服务器,将其转换为主服务器,然后已下线的主服务器的所有从服务器都会改为复制新的主服务器,并将已下线的主服务器设置为新的主服务器的从服务器,当这个旧主服务器重新上线时就会自动称为新的主服务器的从服务器

选取新的master的依据:

(1)排除断线的从服务器

(2)选择优先级最高的从服务器

(3)若从服务器优先级相同,选择复制偏移量最大的从服务器

(4)若偏移量相同,选择运行ID最小的从服务器

7、实践——故障转移模拟

首先我们搭建一个一主二从的redis集群。主服务器的端口为6379,从服务器的端口分别为6380和6381,拓扑关系如下

在这里插入图片描述
对这个集群建立包含三个sentinel的哨兵集群来对服务器进行监控,sentinel的端口分别为26379、26380和26381,拓扑关系如下

在这里插入图片描述

将redis下载文件的解压包中的sentinel.conf文件复制成三分,放在redis的安装目录下,分别作为三个sentinel的配置文件,对配置文件进行修改,其中比较重要的是以下几个配置:

sentinel monitor <master-name> <ip> <redis-port> <quorum>,该命令指定此哨兵监控的主服务器的ip和端口,quorum参数指定有多少个哨兵认为该主服务器主观下线时可以认定其为客观下线;
sentinel down-after-milliseconds <master-name> <milliseconds>,该命令指定多少毫秒后主节点没有应答此哨兵,则可以认定该主节点主观下线
daemonize,指明该Sentinel是否以守护进程运行
logfile,指明日志打印的文件
其他配置可以不用改

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
开启redis集群和三个哨兵后的进程如下

在这里插入图片描述
通过redis-cli连接哨兵后使用 info sentinel命令查看一个哨兵的状态,可以看到哨兵正在监控127.0.0.1:6379,同时也发现了集群中的两个从服务器和其他两个哨兵

在这里插入图片描述

通过redis-cli连接主服务器和从服务器后通过info replication命令查看主从服务器的连接情况

主服务器,可以看到,已有两个服务器连接

在这里插入图片描述
两个从服务器均已连接到主服务器

6380:

在这里插入图片描述
6381:

在这里插入图片描述

此时进入主服务器6379执行shutdown命令,关闭主服务器

在这里插入图片描述

这时候我们查看其中一个哨兵的日志,发现该哨兵在主服务器关闭后首先认定主服务器为sdown状态(即主观下线),当认定master为主观下线的哨兵数量达到quorum(此处为2)时,判定主节点为odown状态(即客观下线)

在这里插入图片描述

选举Leader

在这里插入图片描述

选择6381成为新的master

在这里插入图片描述

最后将6381转换为新的master,并让6379和6380称为6381的从节点

在这里插入图片描述
此时再来查看6381的主从关系,发现6381已经成为了主服务器,并且有一个从服务器连接

在这里插入图片描述

查看6380的主从状态,此时它的主服务器也变成了6381

在这里插入图片描述

当重新启动6379节点时,我们在来查看6381的主传动状态,发现有两个从节点,显然重新上线的6379自动成为了它的从节点

在这里插入图片描述