Redis在linux的安装教程:https://www.yuque.com/keep_zero/rh71uv/vdz1u8

image.png

什么是Redis主从复制?

和Mysql主从复制的情况类似,Redis虽然读写速度都很快,但是访问量大的时候,也会导致Redis读压力过大的情况。Redis主从复制主要是为了分担Redis读压力

Redis主从复制,指的是将一台Redis服务器的数据和操作,复制到其他Redis服务器。前者称为主节点(master),后者称为从节点(slave)**【主从节点数据最终完全一致】。**

一个主节点可以有多个从节点,但是一个从节点只能有一个主节点

主从复制的作用:

1、数据备份:主从复制实现了数据的热备份

2、故障恢复:当主节点出现问题时,可以有从节点提供服务,实现快速的故障恢复

3、负载均衡:配合读写分离,可以让主节点负责写操作服务,由从节点提供读服务,分担服务器负载。由其是写少读多的场景下,通过多个从节点分担读压力,可以大大提高redis并发量

4、高可用基础:Redis集群以及Redis哨兵都要在Redis主从复制的基础上搭建,所以是保证高可用的基础。

主从复制的搭建

简单搭建一主二从的主从复制结构,先学习使用,后学习原理

1、搭建主从结构**

为方便起见,我们在同一台服务器安装三个Redis实例【安装完一个后,直接复制两份出来,修改端口即可】,具体安装步骤可以看前面的文章
image.png
master(主节点):191.168.1.1 6379
slaver1(从节点1): 191.168.1.1 6380
slaver2(从节点2):191.168.1.1 6381

我们需要注意:**主从复制由从节点发起,主节点不需要进行特殊处理

默认所有Redis实例都是主节点,而将Redis设置为从节点,有三种方式:

  • 修改从节点配置文件redis.conf,加入:slaveof <主节点ip> <主节点端口>
  • 启动从节点命令中指定主节点:./src/redis-server —slaveof <主节点ip> <主节点端口>
  • 正常启动从节点后,通过从节点客户端执行命令设置主节点:slaveof <主节点ip> <主节点端口>

我们选择使用配置文件方式搭建
首先看一下,master的配置:

  1. protected-mode yes
  2. port 6379

slaver1的配置:

  1. protected-mode yes
  2. port 6380
  3. slaveof 127.0.0.1 6379 # 由于使用同一个服务器,所以指定主节点ip为127.0.0.1

slaver2的配置:

  1. protected-mode yes
  2. port 6381
  3. slaveof 127.0.0.1 6379 # 由于使用同一个服务器,所以指定主节点ip为127.0.0.1

2、使用

启动主节点

  1. ./redis-marster/src/redis-server ./redis-marster/redis.conf &

image.png

启动从节点1

  1. ./redis-slaver1/src/redis-server ./redis-slaver1/redis.conf &

image.png
启动从节点2

  1. ./redis-slaver2/src/redis-server ./redis-slaver2/redis.conf &

image.png

从上述输出可以看出两个从节点都已经连接上主节点master,主从复制架构搭建完成

下面开始测试:

连接各redis节点的客户端

  1. ./redis-marster/src/redis-cli -p 6379 # 使用主节点客户端
  2. ./redis-slaver1/src/redis-cli -p 6380 # 使用从节点1客户端
  3. ./redis-slaver2/src/redis-cli -p 6381 # 使用从节点2客户端

image.png
image.png
image.png

各节点查询没有的key:
image.png
image.png
image.png

向**master**节点插入key:
image.png
从节点查询:
image.png
image.png

从上述结果可以看到,对master的插入操作被同步到了slaver1和slaver2

从master中删除key:
image.png
从节点查询:**
image.png
image.png

从上述结果可以看到,对master的删除操作也被同步到了slaver1和slaver2

主从复制使得主从节点的数据最终保持一致

3、断开主从复制

连接主从关系之后,可以在从节点客户端执行命令断开主从关系

  1. slaveof no one

值得注意的是,断开主从关系并不会清除该从节点的数据,只是后续所有主节点操作不会同步到该从节点

断开从节点slaver1的主从关系:
image.png
往主节点master添加key
image.png
从节点查询
image.png
**


image.png**

Redis主从复制原理

简单来说,Redis主从复制的目的是保证Redis服务的高可用,而要保证高可用,需要保证两个方面,一个是故障恢复,一个是负载均衡。

怎么复制?

Redis主从复制模式有两种:
**

  • 全量数据同步在从节点启动初始化的时候执行,从节点请求master执行Bg Save命令获取包含所有缓存数据的RDB Snapshot文件,从节点接收完毕后,清除掉自己的旧数据,然后将RDB载入内存

image.png
全量数据同步的同步核心是数据

  • 增量数据同步在从节点初始化完成之后执行,将主节点的写操作【增删改】同步到从节点中。

image.png
增量数据同步的同步核心是操作

主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,从节点在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从节点进行全量同步。

主从复制的过程是异步的,意思就是主从节点在进行复制的过程中,不影响节点的写操作

需要注意,当多个从节点断线重连时,同时发送全量同步请求SYNC,这时候可能会导主节点IO剧增宕机 ** 当然,自Redis2.8以后,从节点断线重连允许直接从中断处继续同步,而不需要重新开始同步,这也是一种解决策略。

怎么切换?

主从复制的故障恢复策略是当主节点故障时,从节点可以切换作为主节点使用,保证服务的可用性(总不能宕了就宕了)

而实现从节点切换为主节点,有两种方式:手动切换哨兵模式

手动切换顾名思义就是当主节点宕机的时候,手动将从节点设置为主节点,在从节点客户端执行下述命令:

  1. slaveof no one

很明显这种方式是很麻烦而且不具备实时性,当然也可以自己写脚本去实现这一过程,就是太复杂了,在生产环境需要快速切换的时候很有可能出现不可服务问题。
**
哨兵模式则是另一种自动化的手段,通过设置哨兵节点监控节点状态,实现自动切换主从节点的功能,具体运用我们看一下补充内容

怎么读写分离?

上面说了,主从复制可以实现读写分离,由主节点负责写操作,而众多从节点负责读操作,这样可以做到负载均衡,减轻Redis读压力。

任何一个redis实例启动的时候都是默认为主节点(如果没有设置为从节点),当成为从节点的时候,默认就是只读状态,不允许进行写操作,如对上述的slaver2节点写内容会报如下信息:
image.png

之所以会有这种结果是因为redis的配置文件redis.conf默认配置了:

  1. slave-read-only yes # 从节点只读

image.png
那么问题来了,当主节点宕机了的时候,从节点是否还提供数据读服务呢?这也是可以配置的:

  1. slave-server-stale-data yes # 当主节点不可用时,是否使用当前数据提供读服务?默认yes,表示仍旧提供读服务

如果仍旧提供,则无法保证提供的数据是否过期数据
image.png

权限验证?

如果是个redis实例都可以连接主节点,从主节点中获取数据,那数据安全性就不存在了,redis主从复制还提供了权限验证机制

如果Master主节点配置了requirepass 参数,则需要密码验证方可连接,从节点必须配置masterauth 参数保证与主节点配置密码一致才可以进行主从复制,否则失败。

主节点配置文件配置requirepass参数,设置主节点密码

  1. requirepass 123456

image.png
从节点1配置文件配置masterauth参数,设置所属主节点的连接密码

  1. masterauth 123456

image.png
从节点2配置文件配置masterauth参数,设置一个错误的主节点密码

  1. masterauth 12345678

image.png
重启三个redis实例:
image.png
image.png
image.png
此处slaver2从节点连接主节点报错主节点权限验证失败,密码错误

  1. MASTER <-> SLAVE sync started
  2. Non blocking connect for SYNC fired the event.
  3. Master replied to PING, replication can continue...
  4. Unable to AUTH to MASTER: -ERR invalid password

主从复制相关配置

  1. slaveof <主节点ip> <主节点端口> # 配置当前redis为从节点,并指定主节点
  2. slave-read-only yes # 从节点只读
  3. slave-server-stale-data yes # 当主节点不可用时,是否使用当前数据提供读服务?默认yes,表示仍旧提供读服务
  4. slave-priority 100 #指定slave权重值,当master失效后,哨兵将会从slave列表中找到权重值最高(>0)的slave,并提升为master。
  5. min-slaves-max-lag 10 #表示从服务器与主服务器的时差不能够相差10秒以上
  6. repl-timeout 60 # slave与master通讯中,最大空闲时间,默认60秒.超时将导致连接关闭
  7. masterauth <主节点密码> # 配置当前redis的主节点连接密码

Redis哨兵模式【Redis Sentinel模式】

image.png

概述


Redis主从复制模式的缺陷就是本身没有办法对master进行动态选举,一旦master主节点宕机,无法自动切换主从节点提供服务。**为了解决这个缺陷,Redis在2.8之后提供了Redis Sentinel【哨兵】架构。

哨兵模式会创建哨兵线程,用于监控redis主从中Master主节点工作的状态,在Master主节点发生故障的时候,可以实现Master和Slave节点的切换,保证系统的高可用(HA)

哨兵线程本质上也是一个特殊的Redis实例,只是担当了哨兵,拥有了以下作用:

1、监控:哨兵会不断检查Master和Slave的状态,判断是否运作正常

2、提醒:当检测到某个Redis节点出现问题时,哨兵可以通过API向管理园或其他应用程序发送通知

3、自动故障切换:当检测的某个Master主节点故障时,哨兵可以将Master下的某个从节点自动升级为主节点,并通知故障Master的其他从节点改为复制新的Master

搭建哨兵模式

在上文一主二从的架构上,添加哨兵角色

拷贝两个redis文件目录,名称分别为redis-sentinel1和redis-sentinel2,两个哨兵Redis
image.png

#修改sentinel.conf文件

修改redis-sentinel1目录下,与redis.conf同级的sentinel.conf文件
image.png

  1. port 26379 # 默认哨兵的端口是26379
  2. sentinel monitor mymaster 127.0.0.1 6379 2 # 配置监听的主节点

image.png
修改redis-sentinel2目录下,与redis.conf同级的sentinel.conf文件

  1. port 26380 # 默认哨兵的端口是26379
  2. sentinel monitor mymaster 127.0.0.1 6379 2 # 配置监听的主节点

注意,无需在哨兵配置中配置从节点信息,因为哨兵会根据主节点发现从节点进行监控


#使用sentinel.conf文件启动两个哨兵**

  1. ./redis-sentinel1/src/redis-server ./redis-sentinel1/sentinel.conf &
  2. ./redis-sentinel2/src/redis-server ./redis-sentinel2/sentinel.conf &

image.png
image.png

可以看到,两个哨兵监听的主节点目前都是6379节点,同时监听着两个从节点

#正常状态下,在客户端通过info命令查看各节点信息

  1. ./redis-xxx/src/redis-cli -p 端口号
  2. info replication

主节点
image.png
从节点1
image.png
从节点2
image.png

#模拟master故障,关停master
**

  1. ./redis-master/src/redis-cli -p 6379 shutdown

此时可以看到,哨兵节点监控日志中显示,切换了监控的主节点为6380,即slaver1;而从节点则变为6381和6379两个节点
image.png

#故障后查看两个从节点的信息

从节点1
image.png
从节点2**
image.png

从上述结果可以知道,当主节点发生故障之后,哨兵是可以实时监测到的,并自动切换属下某个从节点升级为主节点,并更改其余从节点的配置文件相关配置。

此时的slaver2配置文件中配置的主节点信息变成6380
image.png

**

哨兵模式的工作原理

#第一步:监测节点信息,确认主节点、从节点健康状况


1、每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个PING命令。**

2、如果一个实例(instance)距离最后一次有效回复PING命令的时间超过配置文件中的 down-after-milliseconds 选项所指定的值,则这个实例会被Sentinel标记为**主观下线**。 【即在本哨兵眼里你是死了的】

3、如果一个**Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态**。【要求一起盯着这个主节点的哨兵确认一下他死了没】

4、当有足够数量的Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态,则Master会被标记为客观下线。【即当认为主节点已经死掉的哨兵数量达到一定的值时,就认为主节点真的死翘翘了】

sentinel monitor mymaster 127.0.0.1 6379 2

这个配置中的2,指的是当起码2个哨兵认为主节点下线的时候,主节点才会被标记为客观下线

5、在一般情况下,每个Sentinel 会以**每10秒一次的频率向它已知的所有Master,Slave发送 INFO 命令**。【用来确认节点信息】

6、当Master被Sentinel标记为客观下线时,Sentinel 向该Master下的所有Slave发送 INFO命令的频率会从10秒一次改为**每秒一次**。

7、若没有足够数量的Sentinel同意Master已经下线,Master的客观下线状态就会被移除。 若 Master重新向Sentinel 的PING命令返回有效回复,Master的主观下线状态就会被移除。

#第二步:如果主节点客观下线,选举领头哨兵

当一定数量的Sentinel认为主节点已经下线,即主节点客观下线时,需要进行故障恢复。

为了保证同时只有一个哨兵在恢复,需要从哨兵中选举出领头哨兵,这个过程使用了Ratf算法,具体过程如下:

1、发现主节点客观下线的哨兵节点(A)向每个哨兵节点发送命令,要求对象选择自己成为领头哨兵

2、如果目标哨兵节点没有选过其他人,则会同样将A推举为领头哨兵

3、如果A发现有超过半数且超过quorum参数值的哨兵节点同样选择自己成为领头哨兵,则A成功成为领头哨兵

4、当有多个哨兵节点同时参选领头哨兵,则会出现没有任何节点当选的可能,此时每个参选节点将等待一个随机事件重新发起参选请求进行下一轮选举,直到选举成功。

#第三步:领头哨兵通知切换主从节点

选举出领头哨兵之后,就要由领头哨兵进行故障恢复了。

1、在已经死翘翘的主节点下的从节点中挑选一个来充当新的主节点
**

如何挑选? ①所有在线的从节点中,选择优先级最高的节点,即replica-priority参数最大的一个

②优先级相同,则复制的命令偏移量越大(复制越完整)越优先

③如果以上都一样,则选择运行ID较小的从数据库


2、领头哨兵向新的主节点发送
SLAVEOF NO ONE**命令,将其升级为主节点

3、领头哨兵向其余从节点发送SLAVEOF命令重新指定主节点,使其成为新主节点的从节点

4、领头哨兵将旧主节点【死翘翘的那个主节点】更新成新主节点的从节点,这样它活过来之后可以继续以从节点的身份提供服务【好惨】

哨兵模式相关配置

  1. #master-name 所监控主节点名称,可自定义
  2. # ip 所监控主节点ip
  3. # redis-port 所监控主节点端口
  4. # quorum 判定主节点客观下线以及推选领头哨兵最低通过的票数
  5. sentinel monitor master-name ip redis-port quorum # 指定哨兵监控的主节点
  6. sentinel down-after-milliseconds mymaster 60000 # 每隔1秒发送一次PING命令,当超过down-after-milliseconds指定时间后,如果被PING的数据库或节点仍然未回复,则哨兵认为其主观下线
  7. sentinel auth-pass <master-name> <password> # 主节点权限验证

总结

1、Redis主从复制:指的是将一台Redis服务器的数据和操作,复制到其他Redis服务器。前者称为主节点(master),后者称为从节点(slave)**【主从节点数据最终完全一致】。一个主节点可以有多个从节点,但是一个从节点只能有一个主节点

2、主从复制的作用:1、数据备份,2、故障恢复3、负载均衡4、高可用

3、
Redis哨兵模式:为了解决Redis主从复制模式当主节点宕机无法自动故障恢复的缺陷,Redis推出了哨兵结构,通过哨兵监控节点状态,如果主节点故障,可以实现自动转换主从节点,保障服务可用。**