Redis分布式缓存超详细教学(微服务版)!

一、Redis

1. Redis 概述

(1) NoSQL

Redis 是一个 NoSQL 的数据库,NoSQL(Not Only SQL),意思是不仅仅是 SQL,泛指各种非关系型数据库。

(2) 安装 Redis

CentOS7 中安装 Redis 的步骤:

1) 安装编译环境
复制代码
yum -y install cpp binutils glibc-kernheaders glibc-common glibc-devel gcc make
2) 下载 redis 的压缩包并解压
复制代码
wget https://download.redis.io/releases/redis-6.2.6.tar.gz
#说明:如果没有wget,可以使用 yum -y install wget 安装即可

解压:

tar -zxvf redis-6.2.6.tar.gz

3) 进入解压后的目录,编译并安装
复制代码
#进入解压目录
cd redis-6.2.6
#编译
make
#指定安装目录并安装,安装在/usr/local/redis 目录中
make install PREFIX=/usr/local/redis

(3) 启动 Redis 服务

1) 从 Redis 的源码目录中拷贝 redis.conf 到 Redis 的安装目录中
2) 修改 redis.conf 配置文件
复制代码
cd /usr/local/redis/bin
vi redis.conf
#修改如下内容:
#daemonize 的值从 no 改为 yes

存盘退出。

3) 启动 redis 服务
复制代码
./redis-server redis.conf
4) 查看进程状态,看看 redis 进程是否已经启动

(4) 将 Redis 配置为 CentOS 系统的一个服务

1) 将 redis 配置为一个服务
复制代码
# 切换到 /lib/systemd/system 目录,创建 redis.service 文件
cd /lib/systemd/system
vi redis.service

redis.service 文件的内容:注意要将注释部分删除,否则启动服务将会失败

复制代码
[Unit] #启动顺序和依赖关系
Description=redis-server #当前服务的简单描述
After=network.target  #表示network.target或sshd-kegen.service需要启动,那么redis.service需要在它们之后启动
[Service] #启动行为
Type=forking #启动类型,将以 fork()方式启动,此时父进程将退出,子进程将成为主进程
# 定义启动进程时执行的命令
ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/bin/redis.conf
PrivateTmp=true #是否给服务分配独立的临时空间
[Install] #定义如何开机启动
WantedBy=multi-user.target #表示在 multi-user.target 组里的所有服务,都将开机自启动

这样配置之后 Redis 服务器就成了 CentOS 系统的一个服务了,那么就可以使用 CentOS 管理服务的命令来管理 Redis 服务

2) 操作 Redis 服务

我们先将之前启动的 redis 服务器关掉,要不然端口号要冲突:

复制代码
#现在 redis 已经是 CentOS 的一个服务了,就可以像管理其他服务一样管理它
#开机自启动
systemctl enable redis
#启动 redis 服务
systemctl start redis
#查看服务状态
systemctl status redis
#停止服务
systemctl stop redis
#取消开机启动
systemctl disabled redis
3) 防火墙开启 6379 端口号
复制代码
firewall-cmd --zone=public --add-port=6379/tcp --permanent
firewall-cmd --reload
firewall-cmd --list-port
4) 开放 redis 的外部访问

因为默认的 redis 配置仅限于在本地访问,如果想在外部访问,要修改 redis.config 配置文件,注释掉:bind 127.0.0.1 -::1,添加 bind 0.0.0.0,然后重启 redis 服务

2. 客户端登录

(1) 设置环境变量

由于我们经常要用到 redis 的 bin 目录中的程序,所以可以考虑将 bin 目录添加到系统环境变量中:

复制代码
vi /etc/profile
复制代码
#让配置生效
source /etc/profile
复制代码
#去家目录中修改 .bashrc,在系统启动时读取该配置文件然后让环境配置生效
cd ~
vi .bashrc

测试:在任意路径打开 redis 客户端

(2) 客户端登录命令

redis-cli:启动客户端,直接执行的话,默认连接本机(127.0.0.1),端口号为 6379,-h 选项可以指定主机的 IP 地址:

ping:登录成功后,测试联通,回复 pong 表示已联通。

exit:退出客户端。

shutdown:登录之后,发送停止服务的命令

以下三节内容参考redis专栏上一篇文章。

3. Redis 的基本操作(参考在 SpringBoot 中讲的 Redis 的基本操作)

二、SpringBoot 整合 Redis(参考在 SpringBoot 中讲的 SpringBoot 整合Redis)

三、Spring Cache:SpringBoot 整合 Redis 实现缓存(参考在 SpringBoot 中讲的 SpringBoot 整合 Redis 作为缓存)

四、Redis 的持久化

1. Redis 主要工作在内存

内存的特点是断电就会清空数据,所以Redis 在工作的时候,如果发生停电,就要考虑如何减少数据丢失。

2. Redis 提供了不同级别的持久化

RDB 持久化方式能够在指定的时间间隔对数据进行快照的存储。

AOF 持久化方式记录每次对Redis 服务器的写操作,记录在AOF 文件中,当服务器重启的时候会读取AOF 文件重新执行这些命令来恢复原始数据。

使用的时候可以同时开启两种持久化方式。

3. RDB 简介

RDB:在指定的时间间隔内将内存中的数据集快照写入磁盘,恢复时是将快照直接读入内存。

工作机制:每个一段时间就将内存的数据保存在硬盘的文件中。

RDB 模式默认是开启的,如果要进行大规模数据恢复,且对数据完整性不是很敏感,那么 RDB 比 AOF 方式更加高效。

RDB 的缺点是最后一次持久化的数据可能丢失。

(1) RDB 保存策略(修改 redis.config)

  • save 900 100 #900秒内如果至少有100个 key 的值变化,则保存(做快照)

  • save "" #禁用 RDB 模式

(2) RDB 常用属性配置(在 redis.config 中配置)

  • save #保存策略

  • dbfilename #RDB 快照的文件名

  • dir #RDB快照保存的目录

  • stop-writes-on-bgsave-error:是否在备份出错时,继续接受写操作。

  • rdbcompression #设置是否压缩快照

  • rdbchecksum #是否进行数据校验

(3) RDB 数据丢失的情况

两次保存的时间间隔内,服务器宕机,或者发生断电问题。

(4) RDB 的触发

基于自动保存的策略

执行 save 或 bgsave 命令,执行时是阻塞状态

执行 flushdb 命令,也会生成 dump.rdb 快照,但是里面是空的。

执行 shutdown 命令时,也会主动备份数据

4. AOF 简介

AOF 是以日志的形式来记录每一个写操作,将每次对数据的新建或修改的命令保存到指定文件中,Redis 重启的时候读取这个文件,重新执行新建、修改的命令来恢复数据。

AOF 默认是不开启的,需要手动开启

AOF 文件的保存路径,和 RDB 路径一致

当 RDB 和 AOF 存在不一致的情况时,按照 AOF 来恢复,因为 AOF 是对 RDB 的补充,备份周期更短,更可靠。

(1) AOF 保存策略(放在 redis.config)

  • appendfsync always:每次产生一条新的修改数据的命令都执行保存操作;效率低,但是安全。

  • appendfsync everysec:每秒执行一次保存操作,如果在未保存的当前秒内发生断电,仍然会导致一部分数据丢失(即1秒钟的数据)

  • appendfsync no:不保存,将数据交给操作系统来处理,更快,也更不安全的操作。

推荐使用每秒同步一次,这样兼顾速度和安全性

(2) AOF 常用属性(配置在redis.config)

  • appendonly:是否开启AOF功能,默认是关闭的

  • appendfilename:AOF文件名称

  • appendfsync:AOF保存策略,官方建议everysec

  • no-appendfsync-on-write:在重写时,是否执行保存策略,执行重写,可以节省AOF文件的体积,而且在恢复的时候效率也更高

  • auto-aof-rewrite-percentage:重写的触发条件。当目前AOF文件大小超过上一次重写的AOF文件大小的百分之多少进行重写

  • auto-aof-rewrite-min-size:设置允许重写的最小AOF文件大小,避免了达到约定百分比但尺寸仍然很小的情况还要重写。

  • aof-load-truncated:截断设置,如果选择是yes,当截断的aof文件被导入的时候,会自动发布一个log给客户端然后load

示例:一般情况下,我们可以将 RDB 和 AOF 方式都开启

RDB 配置:

AOF 配置:

改完之后重启 redis 服务:

然后进行 redis 的操作:

五、主从复制

1. 主从简介

配置多台 Redis 服务器,以主机和备机身份分开,主机数据更新后,根据配置和策略,自动同步到备机的 master/slaver 机制,Master 以写为主,Slaver 以读为主,二者之间自动同步数据。

目的:读写分离提高 Redis 性能,避免单点故障,容灾快速恢复

原理:每次从机联通后,都会给主机发送 sync 指令,主机立刻进行存盘操作,发送 RDB 文件给从机,从机收到 RDB 文件后,进行全盘加载,之后每次主机的写操作,都会立刻发给从机,从机执行相同的命令。

2. 主从准备

(1) 将原来安装的 redis 复制一份,取名为 redis_slaver1

(2) 在 redis_slaver1 的 bin 目录中重新创建一个配置文件 redis_6380.conf,添加如下内容:

复制代码
include /usr/local/redis_slaver1/bin/redis.conf
pidfile /var/run/redis_6380.pid
port 6380
dbfilename dump_6380.rdb

(3) 防火墙打开 6380 端口

(4) 启动从机服务

(5) 在客户端中验证:

3. 主从建立

(1) 临时建立

在从服务器上执行 "SLAVEOF 主机IP 主机端口",可以通过 "info replication" 命令查看相关星系,可以通过 "SLAVEOF NO ONE" 恢复:

(2) 永久建立

修改从机配置文件 redis_6380.conf,将里面的内容改为如下内容:

复制代码
include /usr/local/redis_slaver1/bin/redis.conf
pidfile /var/run/redis_6380.pid
port 6380
dbfilename dump_6380.rdb
slaveof 127.0.0.1 6379

重启从机:注意:从机只能读,不能写:

六、Redis 集群

Redis 的集群分为主从集群和分片集群

1. Redis 主从集群

(1) 主从集群结构图:

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

我们在CentOS 中开启了 3 个 Redis 实例,模拟主从集群,信息如下:

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

(2) 准备实例和配置

我们要开启 3 个实例,需要准备 3 份不同的配置文件和目录,配置文件所在的目录就是工作目录

1) 创建目录

创建 3 个目录,名称为 7001、7002、7003

复制代码
# 进入/tmp目录
cd /tmp
# 创建目录
mkdir 7001 7002 7003
2) 恢复原始配置

修改 redis 源代码目录"redis-6.2.6/redis.conf",将其中的持久化模式改为默认的 RDB 模式,AOF 保持默认关闭状态

复制代码
# 开启RDB
# save ""
save 3600 1
save 300 100
save 60 10000
​
# 关闭AOF
appendonly no

存盘退出

3) 拷贝配置文件到每个实例的目录

将 redis-6.2.6/redis.conf 文件拷贝到三个实例的目录中:在家目录~执行下列命令

复制代码
cp redis-6.2.6/redis.conf /tmp/7001
cp redis-6.2.6/redis.conf /tmp/7002
cp redis-6.2.6/redis.conf /tmp/7003
4) 修改每个实例的端口号、工作目录

将每个实例的端口号修改为 7001、7002、7003,将每个实例的 rdb 文件保存位置修改为自己所在的目录,以下命令在 /tmp 目录下执行:

复制代码
sed -i -e 's/6379/7001/g' -e 's/dir .\//dir \/tmp\/7001\//g' 7001/redis.conf
sed -i -e 's/6379/7002/g' -e 's/dir .\//dir \/tmp\/7002\//g' 7002/redis.conf
sed -i -e 's/6379/7003/g' -e 's/dir .\//dir \/tmp\/7003\//g' 7003/redis.conf
5) 修改每个实例的声明 IP

虚拟机本身有多个 IP,为了避免将来混乱,我们需要在 redis.conf 找那个指定每一个实例绑定的 IP 地址,格式如下:

复制代码
replica-announce-ip 192.168.200.100

以下命令在 /tmp 目录下执行:

复制代码
# 逐一执行
sed -i '1a replica-announce-ip 192.168.200.100' 7001/redis.conf
sed -i '1a replica-announce-ip 192.168.200.100' 7002/redis.conf
sed -i '1a replica-announce-ip 192.168.200.100' 7003/redis.conf
​
# 或者一键修改
printf '%s\n' 7001 7002 7003 | xargs -I{} -t sed -i '1a replica-announce-ip 192.168.200.100' {}/redis.conf
6) 修改每个实例绑定的 IP 地址,改为外网可以访问

修改每一个 redis.config 文件,注释掉 bind 127.0.0.1 -::1,添加 bind 0.0.0.0

(3) 启动

为了方便查看日志,我们打开3个ssh创建,分别启动 3 个 redis 实例,进入 /tmp 目录,启动命令:

复制代码
# 第1个
redis-server 7001/redis.conf
# 第2个
redis-server 7002/redis.conf
# 第3个
redis-server 7003/redis.conf

(4) 开启主从关系

现在 3 个是还没有任何关系,要配置主从可以使用 replicaof 或 slaveof(5.0之前的命令),有临时和永久两种模式:

修改 redis.conf 配置文件是永久生效,添加一行 slaveof master的IP master的端口

使用 redis-cli 连接 redis 服务,执行 slaveof 命令(临时生效,重启之后失效):

复制代码
slaveof master的IP master的端口

为了演示方便,我们使用第二种方式:

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

复制代码
# 连接 7002
redis-cli -h 192.168.200.100 -p 7002
# 执行slaveof
slaveof 192.168.200.100 7001

新开一个ssh窗口:

同样的方式来配置 7003:

复制代码
# 连接 7003
redis-cli -h 192.168.200.100 -p 7003
# 执行slaveof
slaveof 192.168.200.100 7001

新开一个ssh窗口:

然后连接 7001 主机,查看集群状态

复制代码
# 连接 7001
redis-cli -h 192.168.200.100 -p 7001
# 查看状态
info replication

新开一个ssh窗口:

(5) 测试

在 7001 执行 set num 123,然后分别在 7002,7003 中去 get num ,然后在 7002和7003 去 set num 666,set num 888:

主机读写都行,从机只能读,不能写。

2. 搭建哨兵集群

(1) 集群结构

这里我们搭建一个 3 个节点组成的 Sentinel 集群,来监管之前的 Redis 主从集群,如图:

三个 Sentinel 实例的信息如下:

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

(2) 准备实例和配置

和之前一样创建s1,s2,s3 目录:

复制代码
# 进入/tmp目录
cd /tmp
# 创建目录
mkdir s1 s2 s3

然后我们在 s1 目录中创建一个 sentinel.conf 配置文件,添加如下内容:

复制代码
port 27001
sentinel announce-ip 192.168.200.100
sentinel monitor mymaster 192.168.200.100 7001 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
dir "/tmp/s1"

解读:

port 27001:是当前sentinel实例的端口

sentinel monitor mymaster 192.168.200.137 7001 2:指定主节点信息 --mymaster:主节点名称,自定义,任意写 --192.168.200.100 7001:主节点的ip和端口 --2:选举master时的quorum值

然后将 s1/sentinel.conf 拷贝到 s2、s3 目录中,在/tmp目录下执行如下命令:

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

修改 s2、s3 目录中的配置文件,将端口改为 27002、27003,在/tmp 目录下执行如下命令:

复制代码
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

(3) 启动

为了查看日志,我们使用 3 个 ssh 窗口启动 3 个 redis-sentinel,如下命令在 /tmp 目录中执行

复制代码
# 第1个
redis-sentinel s1/sentinel.conf
# 第2个
redis-sentinel s2/sentinel.conf
# 第3个
redis-sentinel s3/sentinel.conf

(4) 测试

让 master 节点 7001 宕机,查看 sentinel 日志:

查看 sentinel 的日志:

我们来查看当前的 master 7002:

查看从机 7003:

3. 搭建分片集群

(1) 集群结构

分片集群需要的节点数量比较多,这里我们搭建一个最小的分片集群,包含 3 个 master 节点,每个 master 节点包含一个 slave 节点,结构如下:

这里我们需要 6 个 redis 实例,模拟分片集群,信息如下:

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

(2) 准备实例和配置

删除之前的 7001、7002、7003目录,重新创建 7001、7002、7003、8001、8002、8003 目录:

复制代码
# 进入/tmp目录
cd /tmp
# 删除旧的,避免配置干扰
rm -rf 7001 7002 7003
# 创建目录
mkdir 7001 7002 7003 8001 8002 8003

在 /tmp 目录下创建一个 redis.conf 配置文件,内容如下:

复制代码
port 6379
# 开启集群功能
cluster-enabled yes
# 集群的配置文件名称,不需要我们创建,由redis自己维护
cluster-config-file /tmp/6379/nodes.conf
# 节点心跳失败的超时时间
cluster-node-timeout 5000
# 持久化文件存放目录
dir /tmp/6379
# 绑定地址
bind 0.0.0.0
# 让redis后台运行
daemonize yes
# 注册的实例ip
replica-announce-ip 192.168.200.100
# 保护模式
protected-mode no
# 数据库数量
databases 1
# 日志
logfile /tmp/6379/run.log

然后将这个配置文件拷贝到每个目录下:

复制代码
# 进入/tmp目录
cd /tmp
# 执行拷贝:将tmp目录下的redis.conf分别拷贝到7001 7002 7003 8001 8002 8003
echo 7001 7002 7003 8001 8002 8003 | xargs -t -n 1 cp redis.conf

修改每个目录的 redis.conf,将原来的端口号 6379 改为和目录名一致:

复制代码
# 进入/tmp目录
cd /tmp
# 修改配置文件:分别把7001 7002 7003 8001 8002 8003这些目录录下的redis.conf中的6379替换为对应的文件夹名
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t sed -i 's/6379/{}/g' {}/redis.conf

(3) 启动

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

复制代码
#进入/tmp目录
cd /tmp
# 一键启动所有服务
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-server {}/redis.conf

查看一下进程状态:

如果要关闭所有进程,可以执行:

复制代码
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-cli -p {} shutdown

(4) 创建集群

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

我们需要执行命令来创建集群,Redis 5.0 之前创建集群很麻烦,5.0 之后集群管理命令都集成到了 redis-cli 中。我们直接看 5.0 之后的命令,执行如下命令:

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

命令说明:

redis-cli --cluster或者./redis-trib.rb:代表集群操作命令

create:代表是创建集群

--replicas 1或者--cluster-replicas 1 :指定集群中每个master的副本个数为1,此时节点总数 ÷ (replicas + 1) 得到的就是master的数量。因此节点列表中的前n个就是master,其它节点都是slave节点,随机分配到不同master

运行后的结果:

可以看到 7001,7002,7003作为 master,8001,8002,8003随机分配给 master 作为 slaver,没有问题,输入 yes,开始创建集群:

通过命令可以查看集群状态:

redis-cli -p 7001 cluster nodes

(5) 测试

连接 7001 节点,存储一个数据

复制代码
#连接
redis-cli -h 192.168.200.100 -p 7001
#存储数据
set num 123
#读取数据
get num
#再次存储
set a 1

出现问题了,在进行集群操作时,需要给 redis-cli 加上一个 -c 参数才可以:

redis-cli -c -h 192.168.200.100 -p 7001

没有问题了。

SpringBoot 去访问 Redis 的集群,同学们自己百度。

相关推荐
2601_961963382 小时前
React对比Vue对比Angular:构建企业级合同签署平台深度评测
java·微服务·架构
uoKent2 小时前
Redis环境搭建与redis-cli基础操作
数据库·redis·缓存
IT策士16 小时前
Redis 从入门到精通:性能调优与多语言客户端对比
数据库·redis·缓存
青柠代码录17 小时前
【Redis】数据类型:Stream
redis
就改了18 小时前
Zipkin 快速上手部署与接入实战
微服务·zipkin·微服务链路追踪
Yeats_Liao18 小时前
Feed流系统设计(三):数据模型与存储设计,从表结构到Redis收件箱
java·javascript·redis
鹅城剑仙1 天前
Spring Boot 微服务架构设计与最佳实践
spring boot·后端·微服务
很楠爱上1 天前
Docker 从入门到实战:核心概念、微服务编排与环境移植完全指南
docker·微服务·容器
IT策士1 天前
Redis 从入门到精通:Redis Stream —— 可靠消息队列
数据库·redis·缓存