学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存


若文章内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系博主删除。


前言


  • 学习视频链接
    • SpringCloud + RabbitMQ + Docker + Redis + 搜索 + 分布式,史上最全面的 SpringCloud 微服务技术栈课程 | 黑马程序员 Java 微服务
  • 学习资料链接
    • https://pan.baidu.com/s/169SFtYEvel44hRJhmFTRTQ提取码:1234

  • 写这篇博客旨在制作笔记,巩固知识。同时方便个人在线阅览,回顾知识。
  • 博客的内容主要来自视频内容和资料中提供的学习笔记。

  • 参考博客《你知道在 Redis 中 daemonize 的 yes 和 no 有什么区别吗?》

系列目录


SpringCloud 微服务技术栈_实用篇①_基础知识

SpringCloud 微服务技术栈_实用篇②_黑马旅游案例


SpringCloud 微服务技术栈_高级篇①_微服务保护

SpringCloud 微服务技术栈_高级篇②_分布式事务

SpringCloud 微服务技术栈_高级篇③_分布式缓存

SpringCloud 微服务技术栈_高级篇④_多级缓存

SpringCloud 微服务技术栈_高级篇⑤_可靠消息服务


微服务技术栈导学


学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第1张图片


学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第2张图片


上一篇SpringCloud 微服务技术栈_高级篇②_分布式事务


11.解决单点 Redis 的问题


单点 Redis 的问题

  1. 数据丢失问题:Redis 是内存存储,服务重启可能会丢失数据
  2. 并发能力问题:单节点 Redis 的并发能力虽然不错,但也无法满足如 618 这样的高并发场景
  3. 故障恢复问题:如果 Redis 宕机,则服务不可用,需要一种自动的故障修复手段
  4. 存储能力问题:Reids 基于内存,单节点能存储的数据量难以满足海量数据需求

基于 Redis 集群解决单机 Redis 存在的问题

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第3张图片


12.Redis 持久化


Redis 有两种持久化方案

  • RDB 持久化
  • AOF 持久化

12.1.RDB 持久化


12.1.1.RDB 定义


RDB 全称 Redis Database Backup file(Redis 数据备份文件),也被叫做 Redis 数据快照。

简单来说就是把内存中的所有数据都记录到磁盘中。

当 Redis 实例故障重启后,从磁盘读取快照文件,恢复数据。

快照文件称为 RDB 文件,默认是保存在当前运行目录。


12.1.2.执行时机


RDB 持久化在四种情况下会执行

  • 执行 save 命令
  • 执行 bgsave 命令
  • Redis 停机时会执行 save 命令
  • 触发 RDB 的条件(redis.conf 中的内容)

  • 额外记录
    • 太久没用过 redis 了,都快忘记了,故记录一下打开服务客户端的操作

  1. save 命令

执行下面的命令,可以立即执行一次 RDB

redis-cli

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第4张图片
save 命令会导致主进程执行 RDB,这个过程中其它所有命令都会被阻塞。

只有在数据迁移时可能用到。


  1. bgsave 命令

下面的命令可以异步执行 RDB

bgsave

在这里插入图片描述

这个命令执行后会开启独立进程完成 RDB,主进程可以持续处理用户请求,不受影响。


  1. 停机时

Redis 停机时会执行一次 save 命令,实现 RDB 持久化。

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第5张图片
学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第6张图片

但是 redis 的这个持久化在停机时才执行,如果服务器突然宕机了怎么办?


  1. 触发 RDB 条件

Redis 内部有触发 RDB 的机制,可以在 redis.conf 文件中找到,格式如下

  • 第一条的意思:900 秒内,如果至少有 1 个 key 被修改,则执行 bgsave,如果是 save "" 则表示禁用 RDB
  • 其余的意思与第一条意思差不多,只是数值变化了而已
  • 一般默认的设置就可以了,无特殊要求不需要更改
save 900 1  
save 300 10  
save 60 10000 

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第7张图片

RDB 的其它配置也可以在 redis.conf 文件中设置

  • 是否压缩 ,建议不开启,压缩也会消耗 cpu,磁盘的话不值钱
rdbcompression yes

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第8张图片

  • RDB 文件名称
dbfilename dump.rdb  
  • 文件保存的路径目录,./,即当前目录
dir ./ 

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第9张图片


额外记录

  • 我的虚拟机上的 Redis 是在写这篇博客的时候安装的
  • 相关的安装操作、基本配置操作和基本语法都在该博客中说明了。
src/redis-server ./redis.conf # 启动 redis-server

在这里插入图片描述

之前在 redis.conf 文件中写入了 requirepass password,即设置了 Redis 的密码

故启动客户端时需要输入密码

有两种方式:src/redis-cli -h localhost -p 6379src/redis-cli -h localhost -p 6379 -a password

src/redis-cli -h localhost -p 6379 
auth password # 进入到 redis 客户端后输入密码

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第10张图片

src/redis-cli -h localhost -p 6379 -a 123456 # 一步到位,直接命令行中添加密码

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第11张图片


12.1.3.RDB 的底层原理


bgsave 开始时会 fork 主进程得到子进程,子进程共享主进程的内存数据。

完成 fork 后读取内存数据并写入 RDB 文件。

fork 采用的是 copy-on-write 技术

  • 当主进程执行读操作时,访问共享内存;
  • 当主进程执行写操作时,则会拷贝一份数据,执行写操作。

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第12张图片


12.1.4.小结


RDB 方式 bgsave 的基本流程?

  • fork 主进程得到一个子进程,共享内存空间
  • 子进程读取内存数据并写入新的 RDB 文件
  • 用新 RDB 文件替换旧的 RDB 文件

RDB 会在什么时候执行?save 60 1000 代表什么含义?

  • 默认是服务停止时
  • 代表 60 秒内至少执行 1000 次修改则触发 RDB

RDB 的缺点?

  • RDB 执行间隔时间长,两次 RDB 之间写入数据有丢失的风险
  • fork 子进程、压缩、写出 RDB 文件都比较耗时

12.2.AOF 持久化


12.2.1.AOF 原理


AOF 全称为 Append Only File(追加文件)。

Redis 处理的每一个写命令都会记录在 AOF 文件,可以看做是命令日志文件。

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第13张图片


12.2.2.AOF 配置


AOF 默认是关闭的,需要修改 redis.conf 配置文件来开启 AOF

  • 是否开启 AOF 功能,默认是 no
appendonly yes
  • 指定 AOF 文件的名称
appendfilename "appendonly.aof"

AOF 的命令记录的频率也可以通过 redis.conf 文件来配(有三种方式)

  • 表示每执行一次写命令,立即记录到 AOF 文件(该操作完全由主进程完成,安全性最高,性能最低)
appendfsync always 
  • 写命令执行完先放入 AOF 缓冲区,然后表示每隔 1 秒将缓冲区数据写到 AOF 文件,是默认方案
appendfsync everysec 
  • 写命令执行完先放入 AOF 缓冲区,由操作系统决定何时将缓冲区内容写回磁盘
appendfsync no

三种策略对比

配置项 刷盘时机 优点 缺点
Always 同步刷盘 可靠性高,几乎不丢数据 性能影响大
everysec 每秒刷盘 性能适中 最多丢失 1 秒数据
no 操作系统控制 性能最好 可靠性较差,可能丢失大量数据

12.2.3.AOF 文件重写


因为是记录命令,AOF 文件会比 RDB 文件大的多。

而且 AOF 会记录对同一个 key 的多次写操作,但只有最后一次写操作才有意义。

通过执行 bgrewriteaof 命令,可以让 AOF 文件执行重写功能,用最少的命令达到相同效果。

bgrewriteaof

在这里插入图片描述


如图,AOF 原本有三个命令

  • 但是 set num 123set num 666 都是对 num 的操作
  • 第二次会覆盖第一次的值,因此第一个命令记录下来没有意义。
  • 所以重写命令后,AOF 文件内容就是:mset name jack num 666

Redis 也会在触发阈值时自动去重写 AOF 文件。

阈值也可以在 redis.conf 中配置

  • AOF 文件比上次文件 增长超过多少百分比则触发重写
auto-aof-rewrite-percentage 100
  • AOF 文件体积最小多大以上才触发重写
auto-aof-rewrite-min-size 64mb 

12.3.RDB 和 AOF 的区别


RDB 和 AOF 各有自己的优缺点,如果对数据安全性要求较高,在实际开发中往往会 结合 两者来使用

RDB AOF
持久化方式 定时对整个内存做快照 记录每一次执行的命令
数据完整性 不完整,两次备份之间会丢失 相对完整,取决于刷盘策略
文件大小 会有压缩,文件体积小 记录命令,文件体积很大
宕机恢复速度 很快
数据恢复优先级 低,因为数据完整性不如 AOF 高,因为数据完整性更高
系统资源占用 高,大量 CPU 和内存消耗 低,主要是磁盘 IO 资源
但 AOF 重写时会占用大量的 CPU 和内存资源
使用场景 可以容忍数分钟的数据丢失,追求更快的启动速度 对数据安全性要求较高常见

13.Redis 主从


13.1.搭建主从结构


单节点 Redis 的并发能力是有上限的,要进一步提高 Redis 的并发能力,就需要搭建主从集群,实现读写分离。

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第14张图片

具体搭建流程参考课前资料 Redis集群.md

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第15张图片


13.1.0.单机安装 redis-6.2.4


这里就稍稍提一下吧(其实是我自己也想换一下版本:4.0.0 ~ 6.2.4)


  1. 安装依赖
  2. 解压
  3. 编译
  4. 修改配置
  5. 启动 Redis 服务和客户端

  1. 安装依赖

首先需要安装 Redis 所需要的依赖

yum install -y gcc tcl

  1. 解压

然后将课前资料提供的 Redis 安装包上传到虚拟机的任意目录

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第16张图片

我这里放的位置是 /usr/local/redis 目录


解压缩

tar -xvf redis-6.2.4.tar.gz

  1. 编译

进入 redis 目录:

cd redis-6.2.4

运行编译命令

make && make install

如果没有出错的话,那应该就是安装成功了。

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第17张图片


  1. 修改配置

然后修改 redis.conf 文件中的一些配置

  • 绑定地址,默认是 127.0.0.1,会导致只能在本地访问。修改为 0.0.0.0 则可以在任意 IP 访问
bind 0.0.0.0
  • 可以设置数据库数量,这里我设置为 1,之前是 16
databases 1
  • Linux 系统中 redis 服务启动时为霸屏模式(将 daemonize no 改为 daemonize yes 就可以后台运行了)
daemonize yes
  • 开启 redis 的密码校验,设置 redis 的密码(把 # requirepass foobared 修改为 requirepass 你想设的密码)即可。
requirepass 你想设的密码
  • 改为 daemonize 的值 为 yes 后,还想看到日志信息就必须指定日志文件(这个文件可以不创建)
mkdir redisLog # 创建新目录
logfile /usr/local/redis/redis-6.2.4/redisLog/run.log

  1. 启动 Redis 服务和客户端
  • 启动 redis 服务
src/redis-server redis.conf
  • 进入 redis 客户端
src/redis-cli -h localhost -p 6379 -a 你设的密码

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第18张图片

  • 也可以先进入 redis 客户端,再输入密码
src/redis-cli -h localhost -p 6379
auth 你设置的密码

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第19张图片

  • 当然,如果没有设置密码的话,直接使用 redis-server redis.conf 命令就行了
src/redis-server redis.conf

13.1.1.集群结构


我们搭建的主从集群结构如图

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第20张图片

共包含三个节点,一个主节点,两个从节点。

这里我们会在同一台虚拟机中开启 3 个 redis 实例,模拟主从集群,信息如下

IP PORT 角色
192.168.150.101 7001 master
192.168.150.101 7002 slave
192.168.150.101 7003 slave

13.1.2.准备实例和配置


要在同一台虚拟机开启 3 个实例,必须准备三份不同的配置文件和目录,配置文件所在目录也就是工作目录。

  1. 创建目录
  2. 恢复原始配置
  3. 拷贝配置文件到每个实例目录
  4. 修改每个实例的端口、工作目录
  5. 修改每个实例的声明 IP

  1. 创建目录

我们创建三个文件夹,名字分别叫 700170027003

mkdir colonyTests
cd colonyTests
mkdir 7001 7002 7003

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第21张图片


  1. 恢复原始配置(如果你之前改动过配置文件的话)

修改 redis-6.2.4/redis.conf 文件,将其中的持久化模式改为默认的 RDB 模式,AOF 保持关闭状态。

开启 RDB(即注释掉 save ""

# save ""
save 3600 1
save 300 100
save 60 10000

关闭 AOF

appendonly no

  1. 拷贝配置文件到每个实例目录

然后将 redis-6.2.4/redis.conf 文件拷贝到三个目录中

方式一:逐个拷贝

cp /usr/local/redis/redis-6.2.4/redis.conf 7001
cp /usr/local/redis/redis-6.2.4/redis.conf 7002
cp /usr/local/redis/redis-6.2.4/redis.conf 7003

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第22张图片

方式二:管道组合命令,一键拷贝

echo 7001 7002 7003 | xargs -t -n 1 cp /usr/local/redis/redis-6.2.4/redis.conf

  1. 修改每个实例的端口、工作目录

我是在该目录下进行操作的:/usr/local/redis/redis-6.2.4/colonyTests

  • 修改每个文件夹内的配置文件,将端口分别修改为 7001、7002、7003
  • 将 rdb 文件保存位置都修改为自己所在目录
sed -i -e 's/6379/7001/g' -e 's/dir .\//dir \/usr\/local\/redis\/redis-6.2.4\/colonyTests\/7001\//g' 7001/redis.conf
sed -i -e 's/6379/7002/g' -e 's/dir .\//dir \/usr\/local\/redis\/redis-6.2.4\/colonyTests\/7002\//g' 7002/redis.conf
sed -i -e 's/6379/7003/g' -e 's/dir .\//dir \/usr\/local\/redis\/redis-6.2.4\/colonyTests\/7003\//g' 7003/redis.conf

  1. 修改每个实例的声明 IP

我是在该目录下进行操作的:/usr/local/redis/redis-6.2.4/colonyTests

虚拟机本身有多个 IP,为了避免将来混乱,我们需要在 redis.conf 文件中指定每一个实例的绑定 ip 信息,格式如下

  • 设置 redis 实例的声明 IP
replica-announce-ip 192.168.150.101

每个目录都要改,我们一键完成修改

  • 可以逐一执行
sed -i '1a replica-announce-ip 192.168.150.101' 7001/redis.conf
sed -i '1a replica-announce-ip 192.168.150.101' 7002/redis.conf
sed -i '1a replica-announce-ip 192.168.150.101' 7003/redis.conf
  • 也可以一键修改
printf '%s\n' 7001 7002 7003 | xargs -I{} -t sed -i '1a replica-announce-ip 192.168.150.101' {}/redis.conf

13.1.3.启动 / 一键停止


src/redis-server colonyTests/7001/redis.conf 
src/redis-server colonyTests/7002/redis.conf 
src/redis-server colonyTests/7003/redis.conf 

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第23张图片

如果要一键停止,可以运行下面命令

printf '%s\n' 7001 7002 7003 | xargs -I{} -t redis-cli -p {} shutdown

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第24张图片


13.1.4.开启主从关系


现在三个实例还没有任何关系,要配置主从可以使用 replicaof 或者 slaveof5.0 以前)命令。

有临时和永久两种模式

  • 修改配置文件(永久生效)
    • redis.conf 中添加一行配置:slaveof
  • 使用 redis-cli 客户端连接到 redis 服务,执行 slaveof 命令(重启后失效)
slaveof <masterip> <masterport>

注意:在 5.0 以后新增命令 replicaof,与 salveof 效果一致。


这里我们为了演示方便,使用方式二。

以下的命令都是在 /usr/local/redis/redis-6.2.4 目录下执行的

在这里插入图片描述


通过 redis-cli 命令连接 7002,执行下面命令

  • 连接 7002
src/redis-cli -p 7002
  • 执行 slaveof
slaveof 192.168.150.101 7001

通过 redis-cli 命令连接 7003,执行下面命令

  • 连接 7003
redis-cli -p 7003
  • 执行 slaveof
slaveof 192.168.150.101 7001

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第25张图片


然后连接 7001 节点,查看集群状态

  • 连接 7001
redis-cli -p 7001
  • 查看状态
info replication

最终结果

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第26张图片


13.1.5.测试


执行下列操作以测试

  • 利用 redis-cli 连接 7001,执行 set num 123
  • 利用 redis-cli 连接 7002,执行 get num,再执行 set num 666
  • 利用 redis-cli 连接 7003,执行 get num,再执行 set num 888

可以发现,只有在 7001 这个 master 节点上可以执行写操作,7002 和 7003 这两个 slave 节点只能执行读操作。

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第27张图片


13.1.6.小结


可以发现,这里的 redis 主从搭建就是启动三个实例

如果是在不同机器上运行的话,我们连端口都不用改了


  • 问:假设有 A、B 两个 Redis 实例,如何让 B 作为 A 的 slave 节点?
  • 答:在 B 节点执行命令:slave of A的IP A的port

13.2.主从数据同步原理


13.2.1.全量同步


主从第一次建立连接时,会执行全量同步,将 master 节点的所有数据都拷贝给 slave 节点

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第28张图片


这里有一个问题:master 如何得知 slave 是第一次来连接呢?


有两个概念,可以作为判断依据

  • Replication Id
    • 简称 replid,是数据集的标记,id 一致则说明是同一数据集。
    • 每一个 master 都有唯一的 replidslave 则会继承 master 节点的 replid
  • offset
    • 偏移量,随着记录在 repl_baklog 中的数据增多而逐渐增大。
    • slave 完成同步时也会记录当前同步的 offset
    • 如果 slaveoffset 小于 masteroffset,说明 slave 数据落后于 master,需要更新。

因此 slave 做数据同步,必须向 master 声明自己的 replication idoffsetmaster 才可以判断到底需要同步哪些数据。

  • 因为 slave 原本也是一个 master ,有自己的 replidoffset
  • 当第一次变成 slave,与 master 建立连接时,发送的 replidoffset 是自己的 replidoffset

master 判断发现 slave 发送来的 replid 与自己的不一致,说明这是一个全新的 slave,就知道要做全量同步了。

master 会将自己的 replidoffset 都发送给这个 slaveslave 保存这些信息。

以后 slavereplid 就与 master一致了。

因此,master 判断一个节点是否是第一次同步的依据,就是看 replid 是否一致


学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第29张图片
全量同步流程描述

  • slave 节点请求增量同步
  • master 节点判断 replid ,发现不一致,拒绝增量同步
  • master 将完整内存数据生成 RDB,发送 RDBslave
  • slave 清空本地数据,加载 masterRDB
  • masterRDB 期间的命令记录在 repl_baklog,并持续将 log 中的命令发送给 slave
  • slave 执行接收到的命令,保持与 master 之间的同步

13.2.2.增量同步


全量同步需要先做 RDB,然后将 RDB 文件通过网络传输个 slave,成本太高了。

因此除了第一次做 全量同步,其它大多数时候 slavemaster 都是做 增量同步

什么是增量同步?就是只更新 slavemaster 存在差异的部分数据。


学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第30张图片


那么 master 怎么知道 slave 与自己的数据差异在哪里呢?


13.2.3.repl_backlog 原理


master 怎么知道 slave 与自己的数据差异在哪里呢?


这就要说到全量同步时的 repl_baklog 文件了。

这个文件是一个固定大小的数组,只不过数组是环形

也就是说:角标到达数组末尾后,会再次从 0 开始读写,这样数组头部的数据就会被覆盖。


repl_baklog 中会记录 Redis 处理过的命令日志及 offset,包括 master 当前的 offset,和 slave 已经拷贝到的 offset

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第31张图片


slavemasteroffset 之间的差异,就是 salve 需要增量拷贝的数据了。

随着不断有数据写入,masteroffset 逐渐变大,slave 也不断的拷贝,追赶 masteroffset

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第32张图片


直到数组被填满

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第33张图片

此时,如果有新的数据写入,就会覆盖数组中的旧数据。

不过,旧的数据只要是绿色的,说明是已经被同步到 slave 的数据,即便被覆盖了也没什么影响。

因为未同步的仅仅是红色部分。


但是,如果 slave 出现网络阻塞,导致 masteroffset 远远超过了 slaveoffset

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第34张图片

在这里插入图片描述


如果 master 继续写入新数据,其 offset 就会覆盖旧的数据,直到将 slave现在的 offset 也覆盖

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第35张图片

棕色框中的红色部分,就是尚未同步,但是却已经被覆盖的数据。

此时如果 slave 恢复,需要同步,却发现自己的 offset 都没有了,无法完成增量同步了。

只能做全量同步。


注意

  • repl_baklog 大小有上限,写满后会覆盖最早的数据。
  • 如果 slave 断开时间过久,导致尚未备份的数据被覆盖,则无法基于 log 做增量同步,只能再次全量同步

13.3.主从同步优化


主从同步可以保证主从数据的一致性,非常重要。


可以从以下几个方面来优化 Redis 主从集群

  • 提高全量同步的性能
    • master 中配置 repl-diskless-sync yes 启用无磁盘复制,避免全量同步时的磁盘 IO
    • Redis 单节点上的内存占用不要太大,减少 RDB 导致的过多磁盘 IO
  • 尽可能避免全量同步
    • 适当提高 repl_baklog 的大小,发现 slave 宕机时尽快实现故障恢复,尽可能避免全量同步
  • 减小主节点压力同步
    • 限制一个 master 上的 slave 节点数量,如果实在是太多 slave,则可以采用 主-从-从 链式结构,减少 master 压力

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第36张图片

主从从架构图

13.4.小结


简述全量同步和增量同步区别?

  • 全量同步:master将完整内存数据生成 RDB,发送 RDBslave。后续命令则记录在 repl_baklog,逐个发送给 slave
  • 增量同步:slave 提交自己的 offsetmastermaster 获取 repl_baklog 中从 offset 之后的命令给 slave

什么时候执行全量同步?

  • slave 节点第一次连接 master 节点时
  • slave 节点断开时间太久,repl_baklog 中的 offset 已经被覆盖时

什么时候执行增量同步?

  • slave 节点断开又恢复,并且在 repl_baklog 中能找到 offset

14.Redis 哨兵


思考slave 节点宕机回复后可以找 master 节点同步数据,那 master 节点宕机怎么办?


Redis 提供了哨兵(Sentinel)机制来实现主从集群的自动故障恢复。


14.1.哨兵原理


14.1.1.集群结构和作用


学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第37张图片

哨兵的结构图

哨兵的作用

  • 监控:Sentinel 会不断检查您的 masterslave 是否按预期工作
  • 自动故障恢复:如果 master 故障,Sentinel 会将一个 slave 提升为 master。当故障实例恢复后也以新的 master 为主
  • 通知:Sentinel 充当 Redis 客户端的服务发现来源,当集群发生故障转移时,会将最新信息推送给 Redis 的客户端

14.1.2.集群监控原理


Sentinel 基于心跳机制监测服务状态,每隔 1 秒向集群的每个实例发送 ping 命令

  • 主观下线
    • 如果某 sentinel 节点发现某实例未在规定时间响应,则认为该实例 主观下线
  • 客观下线
    • 若超过指定数量(quorum)的 sentinel 都认为该实例主观下线,则该实例 客观下线
    • quorum 值最好超过 Sentinel 实例数量的一半。

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第38张图片


14.1.3.集群故障恢复原理


一旦发现 master 故障,sentinel 需要在 salve 中选择一个作为新的 master,选择依据是这样的

  • 首先会判断 slave 节点与 master 节点断开时间长短
    • 如果超过指定值(down-after-milliseconds * 10)则会排除该 slave 节点
  • 然后判断 slave 节点的 slave-priority 值,越小优先级越高,如果是 0 则永不参与选举
    • slave priority 基本上都一样,默认都是 1
  • 如果 slave-prority 一样,则判断 slave 节点的 offset 值,越大说明数据越新,优先级越高
    • 到这一步还没有区别的话,其实就说明几个节点完全没有区别,之后其实就是随便选
  • 最后是判断 slave 节点的运行 id 大小,越小优先级越高。
    • redis 集群启动的由 redis 那一刻生成的运行 id,它的大小是随机的
    • 所以这最后一步其实就是随机选的

显然,最重要的衡量标准还是 offset


当选出一个新的 master后,该如何实现切换呢?

流程如下

  • sentinel 给备选的 slave1 节点发送 slaveof no one 命令,让该节点成为 master
  • sentinel 给所有其它 slave 发送 slaveof 192.168.150.101 7002 命令
    • 让这些 slave 成为新 master 的从节点,开始从新的 master 上同步数据。
  • 最后,sentinel 将故障节点标记为 slave,当故障节点恢复后会自动成为新的 masterslave 节点

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第39张图片


14.1.4.小结


Sentinel 的三个作用是什么?

  • 监控
  • 故障转移
  • 通知

Sentinel 如何判断一个 redis 实例是否健康?

  • 每隔 1 秒发送一次 ping 命令,如果超过一定时间没有相向则认为是主观下线
  • 如果大多数 sentinel 都认为实例主观下线,则判定服务下线

故障转移步骤有哪些?

  • 首先选定一个 slave 作为新的 master,执行 slaveof no one
  • 然后让所有节点都执行 slaveofmaster
  • 修改故障节点配置,添加 slaveofmaster

14.2.搭建哨兵集群


具体搭建流程参考课前资料:Redis集群.md

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第40张图片


14.2.1.集群结构


这里我们搭建一个三节点形成的 Sentinel 集群,来监管之前的 Redis 主从集群。

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第41张图片


三个 sentinel 实例信息如下

节点 IP PORT
s1 192.168.150.101 27001
s2 192.168.150.101 27002
s3 192.168.150.101 27003

14.2.2.准备实例和配置


要在同一台虚拟机开启 3 个实例,必须准备三份不同的配置文件和目录,配置文件所在目录也就是工作目录。


我们创建三个文件夹,名字分别叫 s1s2s3

  • 进入诸位自己安装 redis 的目录
 cd /usr/local/redis/redis-6.2.4/
  • 创建目录
mkdir sentinelTests
cd sentinelTests
mkdir s1 s2 s3

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第42张图片


然后我们在 s1 目录创建一个 sentinel.conf 文件,添加下面的内容

port 27001
sentinel announce-ip 192.168.150.101
sentinel monitor mymaster 192.168.150.101 7001 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
dir "/usr/local/redis/redis-6.2.4/sentinelTests/s1"
daemonize yes

解读:

  • port 27001:是当前 sentinel 实例的端口
  • sentinel monitor mymaster 192.168.150.101 7001 2:指定主节点信息
    • mymaster:主节点名称,自定义,任意写
    • 192.168.150.101 7001:主节点的 ip 和端口
    • 2:选举 master 时的 quorum 值
  • sentinel down-after-milliseconds mymaster 5000slavemaster 断开最长超时时间
  • sentinel failover-timeout mymaster 60000slave 故障恢复超时时间
  • dir "/usr/local/redis/redis-6.2.4/sentinelTests/s1"":工作目录
  • daemonize yes:指定 redis 用守护线程的方式启动

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第43张图片


参考博客:《你知道在 Redis 中 daemonize 的 yes 和 no 有什么区别吗?》

  • 采用 yes
    • redis 会在后台运行,此时 redis 将一直运行,除非手动 kill 该进程。
    • 同时将进程 pid 号写入至 redis.conf 选项 pidfile 设置的文件中(默认会生成在 /var/run/redis.pid)
    • 也可以通过 pidfile 来指定 pid 文件生成的位置(例如:pidfile /path/redis.pid
  • 采用 no
    • 当前界面将进入 redis 的命令行界面,exit 强制退出或者关闭连接工具(putty、xshell 等)都会导致 redis 进程退出。

然后将 s1/sentinel.conf 文件拷贝到 s2s3 两个目录中

(我的操作目录:/usr/local/redis/redis-6.2.4/sentinelTests/

  • 方式一:逐个拷贝
cp s1/sentinel.conf s2
cp s1/sentinel.conf s3
  • 方式二:管道组合命令,一键拷贝
echo s2 s3 | xargs -t -n 1 cp s1/sentinel.conf

修改 s2s3 两个文件夹内的配置文件,将端口分别修改为 27002、27003

(我的操作目录:/usr/local/redis/redis-6.2.4/sentinelTests/

sed -i -e 's/27001/27002/g' -e 's/s1/s2/g' s2/sentinel.conf
sed -i -e 's/27001/27003/g' -e 's/s1/s3/g' s3/sentinel.conf

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第44张图片


14.2.3.启动


分别启动 3 个 redis 实例,启动命令

(我的操作目录:/usr/local/redis/redis-6.2.4/sentinelTests/

  • 第 1 个
src/redis-sentinel sentinelTests/s1/sentinel.conf
  • 第 2 个
src/redis-sentinel sentinelTests/s2/sentinel.conf
  • 第 3 个
src/redis-sentinel sentinelTests/s3/sentinel.conf

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第45张图片


14.2.4.测试


在尝试让 7001(master) 断开后,进入 redis 客户端(端口:7002)

发现其已经变为了 master 节点

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第46张图片
再次尝试启动 7001 端口时,master 也不会发生变化了,仍然是 7002

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第47张图片


  • 以下的三张图片是黑马官方免费公开的笔记文档中的图片
  • 视频中采用的是霸屏模式启动的 redis-serversentinel
  • 图片上有详细介绍。字太多了,所以我直接把他们的图片贴上去了

  • 尝试让 master 节点 7001 宕机,查看 sentinel 日志

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第48张图片


  • 查看 7003 的日志

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第49张图片


  • 查看 7002 的日志

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第50张图片


14.3.RedisTemplate


在 Sentinel 集群监管下的 Redis 主从集群,其节点会因为自动故障转移而发生变化。

Redis 的客户端必须感知这种变化,及时更新连接信息。

Spring 的 RedisTemplate 底层利用 lettuce 实现了节点的感知和自动切换。

下面,我们通过一个测试来实现 RedisTemplate 集成哨兵机制。


14.3.1.导入 Demo 工程


引入课前资料提供的 Demo 工程

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第51张图片


学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第52张图片


14.3.2.引入依赖


在项目的 pom 文件中引入依赖

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-data-redisartifactId>
dependency>

14.3.3.配置 Redis 地址


然后在配置文件 application.yml 中指定 redis 的 sentinel 相关信息

spring:
  redis:
    sentinel:
      master: mymaster # 指定 master 名称
      nodes: # 指定 redis-sentinel 集群信息
        - 192.168.2.7:27001
        - 192.168.2.7:27002
        - 192.168.2.7:27003

14.3.4.配置读写分离


在项目的启动类中,添加一个新的 bean

src/main/java/cn/itcast/redisdemo/RedisDemoApplication.java

@Bean
public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer(){
    return clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);
}

这个 bean 中配置的就是读写策略,包括四种

  • MASTER:从主节点读取
  • MASTER_PREFERRED:优先从 master 节点读取,master 不可用才读取 replica
  • REPLICA:从 slavereplica)节点读取
  • REPLICA _PREFERRED:优先从 slavereplica)节点读取,所有的 slave 都不可用才读取 master

15.Redis 分片集群


15.1.搭建分片集群


15.1.1.分片集群基本介绍


主从和哨兵可以解决高可用、高并发读的问题。

但是依然有两个问题没有解决:

  • 海量数据存储问题
  • 高并发写的问题

使用 分片集群 可以解决上述问题,如图

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第53张图片


分片集群特征

  • 集群中有多个 master,每个 master 保存不同数据
  • 每个 master 都可以有多个 slave 节点
  • master 之间通过 ping 监测彼此健康状态
  • 客户端请求可以访问集群任意节点,最终都会被转发到正确节点

具体搭建流程参考课前资料:Redis 集群.md

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第54张图片


15.1.2.集群结构


分片集群需要的节点数量较多,这里我们搭建一个最小的分片集群

  • 包含 3 个 master 节点,每个 master 包含一个 slave 节点

结构如下

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第55张图片

这里我们会在同一台虚拟机中开启 6 个 redis 实例,模拟分片集群

信息如下

IP PORT 角色
192.168.150.101 7001 master
192.168.150.101 7002 master
192.168.150.101 7003 master
192.168.150.101 8001 slave
192.168.150.101 8002 slave
192.168.150.101 8003 slave

15.1.3.准备实例和配置


我的 redis 安装在了 /usr/local/redis/redis/redis-6.2.4

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第56张图片


删除之前的 700170027003 这几个目录,重新创建出 700170027003800180028003 目录

  • 进入 redis 的目录
cd /usr/local/redis/redis/redis-6.2.4
  • 删除旧的目录,避免配置干扰
rm -rf colonyTests/7001
rm -rf colonyTests/7002
rm -rf colonyTests/7003
  • 创建目录
cd colonyTests/
mkdir 7001 7002 7003 8001 8002 8003

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第57张图片


在目录 /usr/local/redis/redis-6.2.4/colonyTests 准备一个新的 redis.conf 文件

  • 新的 redis.conf 内容如下
port 7001
# 开启集群功能
cluster-enabled yes
# 集群的配置文件名称,不需要我们创建,由 redis 自己维护
cluster-config-file /usr/local/redis/redis-6.2.4/colonyTests/7001/nodes.conf
# 节点心跳失败的超时时间
cluster-node-timeout 5000
# 持久化文件存放目录
dir /usr/local/redis/redis-6.2.4/colonyTests/7001
# 绑定地址
bind 0.0.0.0
# 守护进程,让 redis 后台运行
daemonize yes
# 注册的实例 ip
replica-announce-ip 192.168.150.101
# 关闭掉保护模式后,将来就不做什么用户名密码之类的校验了
protected-mode no
# 数据库数量
databases 1
# 日志
logfile /usr/local/redis/redis-6.2.4/colonyTests/7001/run.log

将这个文件拷贝到每个目录下

  • 进入相应的目录
cd /usr/local/redis/redis-6.2.4/colonyTests
  • 执行拷贝
echo 7001 7002 7003 8001 8002 8003 | xargs -t -n 1 cp redis.conf

修改每个目录下的 redis.conf,将其中的 7001 修改为与所在目录一致

  • 进入相应目录
cd /usr/local/redis/redis-6.2.4/colonyTests
  • 修改配置文件
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t sed -i 's/7001/{}/g' {}/redis.conf

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第58张图片


15.1.4.一键开启所有进程


因为已经配置了后台启动模式,所以可以直接启动服务

  • 进入相应的目录
cd /usr/local/redis/redis-6.2.4/colonyTests
  • 一键启动所有服务
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-server {}/redis.conf
  • 通过 ps 查看状态
ps -ef | grep redis

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第59张图片


15.1.5.一键关闭所有进程


  • 如果要关闭所有进程,可以执行如下命令
ps -ef | grep redis | awk '{print $2}' | xargs kill
  • 或使用该命令关闭所有 redis 的进程(推荐
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-cli -p {} shutdown

15.1.6.创建集群(Redis 5.0 之前)


虽然服务启动了,但是目前每个服务之间都是独立的,没有任何关联。

我们需要执行命令来创建集群,在 Redis 5.0 之前创建集群比较麻烦

Redis 5.0 之后集群管理命令都集成到了 redis-cli 中。


Redis 5.0 之前集群命令都是用 redis 安装包下的 src/redis-trib.rb 来实现的。

因为 redis-trib.rb 是有 ruby 语言编写的所以需要安装 ruby 环境。

  • 安装依赖
yum -y install zlib ruby rubygems
gem install redis

然后通过命令来管理集群

  • 进入 redis 的 src目录
cd /tmp/redis-6.2.4/src
  • 创建集群
./redis-trib.rb create --replicas 1 192.168.150.101:7001 \
192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003

15.1.7.创建集群(Redis 5.0 之后)


虽然服务启动了,但是目前每个服务之间都是独立的,没有任何关联。

我们需要执行命令来创建集群,在 Redis 5.0 之前创建集群比较麻烦

Redis 5.0 之后集群管理命令都集成到了 redis-cli 中。


我们使用的是 redis-6.2.4 版本,集群管理以及集成到了 redis-cli 中,格式如下

redis-cli --cluster create --cluster-replicas 1 192.168.150.101:7001 \
192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003

命令说明

  • redis-cli --cluster 或者 ./redis-trib.rb:代表集群操作命令
  • create:代表是创建集群
  • --replicas 1 或者 --cluster-replicas 1:指定集群中每个 master 的副本个数为 1
    • 此时 节点总数 ÷ (replicas + 1) 得到的就是 master 的数量。
    • 因此节点列表中的前 n 个就是 master,其它节点都是 slave 节点,随机分配到不同 master

运行上面的命令后,需要输入 yes

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第60张图片


之后集群就开始创建了

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第61张图片


  • 通过命令可以查看集群状态
redis-cli -p 7001 cluster nodes

在这里插入图片描述


15.2.散列插槽


15.2.1.插槽原理


这里我偷个懒,直接贴的官方免费公开提供的资料里的图片


Redis 会把每一个 master 节点映射到 0~16383 共 16384个 插槽hash slot)上,查看集群信息时就能看到

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第62张图片


每个 master 都可以存储数据。

当数据存储完毕时,如何得知去哪个 master 找数据?

插槽就可以帮我们解决这个问题


数据 key 不是与节点绑定,而是与插槽绑定。

redis 会根据 key 的有效部分计算插槽值,分两种情况

  • key 中包含 “{}”,且 “{}”中至少包含 1 个字符,“{}” 中的部分是有效部分
  • key 中不包含 “{}”,整个 key 都是有效部分

例如:keynum,那么就根据 num 计算,如果是 {itcast} num,则根据 itcast 计算。


计算方式是利用 CRC16 算法得到一个 hash 值,然后对 16384 取余,得到的结果就是 slot 值。

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第63张图片

在 7001 这个节点执行 set a 1 时,对 a 做 hash 运算,对 16384 取余,得到的结果是 15495,因此要存储到 7003 节点。

到了 7003 后,执行 get num 时,对 num 做 hash 运算,对 16384 取余,得到的结果是 2765,因此需要切换到 7001 节点


插槽与 key 绑定,而不与节点绑定,还可以有效避免节点宕机的情况


15.2.2.小结


Redis 如何判断某个 key 应该在哪个实例?

  • 将 16384 个插槽分配到不同的实例
  • 根据 key 的有效部分计算哈希值,对 16384 取余
  • 余数作为插槽,寻找插槽所在实例即可

如何将同一类数据固定的保存在同一个 Redis 实例?

  • 这一类数据使用相同的有效部分(例如 key 都以 {typeId} 为前缀)

例如:

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第64张图片


15.3.集群伸缩


这里我偷个懒,直接贴的官方免费公开提供的资料里的图片


15.3.1.简述


集群可以添加节点,也可以删除节点


redis-cli --cluster 提供了很多操作集群的命令,可以通过下面方式查看

redis-cli --cluster help

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第65张图片


比如,添加节点的命令

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第66张图片

在没有 --cluster-slave 这个参数前,默认新增节点是主节点

--cluster-master-id 则是指定谁是它的 master(显然这要配合 --cluster-slave 来使用)


15.3.2.需求分析


需求:向集群中添加一个新的 master节点,并向其中存储 num = 10

  • 启动一个新的 redis 实例,端口为 7004
  • 添加 7004 到之前的集群,并作为一个 master 节点
  • 给 7004 节点分配插槽,使得 num 这个 key 可以存储到 7004 实例

这里需要两个新的功能

  • 添加一个节点到集群中
  • 将部分插槽分配到新插槽

15.3.3.创建新的 redis 实例


  • 进入相应的目录
cd /usr/local/redis/redis-6.2.4/colonyTests
  • 创建一个文件夹
mkdir 7004
  • 拷贝配置文件
cp 7001/redis.conf 7004
  • 修改配置文件
sed -i /s/7001/7004/g 7004/redis.conf
  • 启动
redis-server 7004/redis.conf

15.3.4.添加新节点到 redis


添加节点的语法如下:

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第67张图片


  • 执行命令
redis-cli --cluster add-node  192.168.150.101:7004 192.168.150.101:7001

  • 通过命令查看集群状态
redis-cli -p 7001 cluster nodes

如图,7004 加入了集群,并且默认是一个 master 节点:

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第68张图片

但是,可以看到 7004 节点的插槽数量为 0,因此没有任何数据可以存储到 7004 上


15.3.5.转移插槽


我们要将 num 存储到 7004 节点,因此需要先看看 num 的插槽是多少

在这里插入图片描述

如上图所示,num 的插槽为 2765.


我们可以将 0~3000 的插槽从 7001 转移到 7004,命令格式如下

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第69张图片


具体命令如下

建立连接

redis-cli --cluster reshard 192.168.150.101:7001

得到下面的反馈

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第70张图片

询问要移动多少个插槽,我们计划是 3000 个

新的问题来了:

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第71张图片

哪个 node 来接收这些插槽???

显然是 7004,那么 7004 节点的 id 是多少呢?

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第72张图片

复制这个 id,然后拷贝到刚才的控制台后

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第73张图片

这里询问,你的插槽是从哪里移动过来的?

  • all:代表全部,也就是三个节点各转移一部分
  • 具体的 id:目标节点的 id
  • done:没有了

这里我们要从7001获取,因此填写 7001 的 id

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第74张图片

填完后,点击 done,这样插槽转移就准备好了

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第75张图片

确认要转移吗?输入 yes

然后,通过命令查看结果

redis-cli -p 7001 cluster nodes

可以看到

在这里插入图片描述

显然,目的达成。


15.4.故障转移


集群初始状态是这样的

在这里插入图片描述

其中 7001、7002、7003 都是 master,我们计划让 7002 宕机。


15.4.1.自动故障转移


当集群中有一个 master 宕机会发生什么呢?

直接停止一个 redis 实例,例如 7002

redis-cli -p 7002 shutdown

  1. 首先是该实例与其它实例失去连接

  1. 然后是疑似宕机

在这里插入图片描述


  1. 最后是确定下线,自动提升一个 slave为新的 master

在这里插入图片描述


  1. 当 7002 再次启动,就会变为一个 slave 节点了

在这里插入图片描述


15.4.2.手动故障转移


利用 cluster failover 命令可以手动让集群中的某个 master 宕机

切换到执行 cluster failover 命令的这个 slave 节点,实现无感知的数据迁移。


其流程如下:

学习笔记:SpringCloud 微服务技术栈_高级篇③_分布式缓存_第76张图片


这种 failover 命令可以指定三种模式

  • 缺省:默认的流程:如图 1~6 步
  • force:省略了对 offset 的一致性校验
  • takeover:直接执行第 5 歩,忽略数据一致性、忽略 master 状态和其它 master 的意见

案例需求:在 7002 这个 slave 节点执行手动故障转移,重新夺回 master 地位


步骤如下

  1. 利用 redis-cli 连接 7002 这个节点
  2. 执行 cluster failover 命令

如图:

在这里插入图片描述

效果:

在这里插入图片描述


15.5.RedisTemplate 访问分片集群


RedisTemplate 底层同样基于 lettuce 实现了分片集群的支持,而使用的步骤与哨兵模式基本一致

  1. 引入 redis 的 starter 依赖
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-data-redisartifactId>
dependency>
  1. 配置分片集群地址
  2. 配置读写分离

src/main/java/cn/itcast/redisdemo/RedisDemoApplication.java

@Bean
public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer(){
    return clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);
}

与哨兵模式相比,其中只有分片集群的配置方式略有差异

spring:
  redis:
    cluster:
      nodes:
        - 192.168.150.101:7001
        - 192.168.150.101:7002
        - 192.168.150.101:7003
        - 192.168.150.101:8001
        - 192.168.150.101:8002
        - 192.168.150.101:8003

下一篇SpringCloud 微服务技术栈_高级篇④_多级缓存


你可能感兴趣的:(微服务,redis,分布式,缓存,微服务,springcloud)