分布式缓存
分布式缓存
redis版本6.2.4
Redis持久化
RDB (Redis Database Backup file) Redis数据备份文件
AOF (Append Only File) 追加文件
RDB持久化在四种情况下会执行:
- 执行save命令:同步保存,会导致其他命令被阻塞
- 执行bgsave命令:background save 异步保存,不会影响主进程
- Redis停机时:自动执行save命令
- 触发RDB条件时
AOF原理
- Redis处理的每一个写命令都会记录在AOF文件,可以看做是命令日志文件,记录的是步骤
设置RDB触发条件
修改redis目录下的redis.conf文件
1
2
3
4
5
6
7
8
9
10
11
12
13# 900秒内,如果至少有1个key被修改,则执行bgsave , 如果是save "" 则表示禁用RDB
save 900 1
save 300 10
save 60 10000
# 是否压缩 ,建议不开启,压缩也会消耗cpu,磁盘的话不值钱
rdbcompression yes
# RDB文件名称
dbfilename dump.rdb
# 文件保存的路径目录
dir ./
设置AOF
开启AOF
1
2
3
4
5#修改配置文件
appendonly no --> appendonly yes
#AOF文件名
appendfilename "appendonly.aof"设置记录频率
1
2
3
4
5
6
7# always: 每执行一次写命令,立即记录到AOF文件
# every sync: 写命令执行完先放入AOF缓冲区,然后表示每隔1秒将缓冲区数据写到AOF文件,是默认方案
# no: 写命令执行完先放入AOF缓冲区,由操作系统决定何时将缓冲区内容写回磁盘
# appendfsync always
appendfsync everysec
# appendfsync no
因为是记录命令,AOF文件会比RDB文件大的多,故需要重写AOF文件来压缩体积
设置重写触发条件
1
2
3
4# AOF文件比上次文件 增长超过多少百分比则触发重写
auto-aof-rewrite-percentage 100
# AOF文件体积最小多大以上才触发重写
auto-aof-rewrite-min-size 64mb
RDB和AOF比较
Redis主从节点
配置主从节点
准备实例和配置
1
2
3
4# 复制三份redis.conf配置文件到不同的文件夹下
cp redis-4.0.0/redis.conf 7001
cp redis-4.0.0/redis.conf 7002
cp redis-4.0.0/redis.conf 7003修改端口和工作目录
1
2
3sed -i -e 's/6379/7001/g' -e 's/dir .\//dir \/home\/cyx\/redis\/7001\//g' 7001/redis.conf
sed -i -e 's/6379/7002/g' -e 's/dir .\//dir \/home\/cyx\/redis\/7002\//g' 7002/redis.conf
sed -i -e 's/6379/7003/g' -e 's/dir .\//dir \/home\/cyx\/redis\/7003\//g' 7003/redis.conf修改每个实例的声明IP
虚拟机本身有多个IP,为了避免将来混乱,我们需要在redis.conf文件中指定每一个实例的绑定ip信息,
1
2
3sed -i '1a slave-announce-ip 192.168.229.128' 7001/redis.conf
sed -i '1a slave-announce-ip 192.168.229.128' 7002/redis.conf
sed -i '1a slave-announce-ip 192.168.229.128' 7003/redis.conf启动服务端
1
2
3
4
5
6# 分别启动三个服务端
[root@root src]# ./redis-server ../../7001/redis.conf
[root@root src]# ./redis-server ../../7002/redis.conf
[root@root src]# ./redis-server ../../7003/redis.conf客户端连接
1
2# -p选择端口
redis-cli -p 7001配置主从节点
有临时和永久两种模式:
修改配置文件(永久生效)
- 在redis.conf中添加一行配置:
slaveof <masterip> <masterport>
- 在redis.conf中添加一行配置:
使用redis-cli客户端连接到redis服务,执行slaveof命令(重启后失效)
1
2
3
4
5
6
7
8
9# 连接 7002
redis-cli -p 7002
# 执行slaveof
slaveof 192.168.229.128 7001
# 连接 7003
redis-cli -p 7003
# 执行slaveof
slaveof 192.168.229.128 7001测试
通过7001端口的主节点写入数据,在从节点也能读得到
主从同步流程
概念
- Replication Id:简称replid,是数据集的标记,id一致则说明是同一数据集。每一个master都有唯一的replid,slave则会继承master节点的replid
- offset:偏移量,随着记录在repl_baklog中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset。如果slave的offset小于master的offset,说明slave数据落后于master,需要更新。
因此slave做数据同步,必须向master声明自己的replication id 和offset,master才可以判断到底需要同步哪些数据。
完整流程描述:
- slave节点请求增量同步
- master节点判断replid,发现不一致,拒绝增量同步
- master将完整内存数据生成RDB,发送RDB到slave
- slave清空本地数据,加载master的RDB
- master将RDB期间的命令记录在repl_baklog,并持续将log中的命令发送给slave
- slave执行接收到的命令,保持与master之间的同步
Redis哨兵
Redis提供了哨兵(Sentinel)机制来实现主从集群的自动故障恢复。
哨兵作用
哨兵的作用如下:
- 监控:Sentinel 会不断检查您的master和slave是否按预期工作
- 自动故障恢复:如果master故障,Sentinel会将一个slave提升为master。当故障实例恢复后也以新的master为主
- 通知:Sentinel充当Redis客户端的服务发现来源,当集群发生故障转移时,会将最新信息推送给Redis的客户端
Sentinel如何判断一个redis实例是否健康
- 每隔1秒发送一次ping命令,如果超过一定时间没有相向则认为是主观下线
- 如果大多数sentinel都认为实例主观下线,则判定服务下线
故障转移步骤有哪些?
- 首先选定一个slave作为新的master,执行slaveof no one
- 然后让所有节点都执行slaveof 新master
- 修改故障节点配置,添加slaveof 新master
配置哨兵节点
准备实例和配置
1
# 创建三个文件夹,存放sentinel的配置文件
每个目录下创建一个sentinel.conf文件
1
2
3
4
5
6port 27001
sentinel announce-ip 192.168.229.128
sentinel monitor mymaster 192.168.229.128 7001 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
dir "/home/cyx/redis/sentinel1"解读:
port 27001
:是当前sentinel实例的端口sentinel monitor mymaster 192.168.150.101 7001 2
:指定主节点信息mymaster
:主节点名称,自定义,任意写192.168.150.101 7001
:主节点的ip和端口2
:选举master时的quorum值
修改每个配置文件的端口
port XXX
启动
1
2
3
4
5
6# 第1个
./redis-sentinel ../../sentinel1/sentinel.conf
# 第2个
./redis-sentinel ../../sentinel2/sentinel.conf
# 第3个
./redis-sentinel ../../sentinel3/sentinel.conf出现无法故障转移的时候,试试把从节点的slaveof 改成 slaveof 127.0.0.1 主节点端口
RedisTemplate
导入坐标
1 |
|
配置Redis地址
然后在配置文件application.yml中指定redis的sentinel相关信息:
1 |
|
配置读写分离
在项目的启动类中,添加一个新的bean:
1 |
|
这个bean中配置的就是读写策略,包括四种:
- MASTER:从主节点读取
- MASTER_PREFERRED:优先从master节点读取,master不可用才读取replica
- REPLICA:从slave(replica)节点读取
- REPLICA _PREFERRED:优先从slave(replica)节点读取,所有的slave都不可用才读取master
Redis分片集群
概念
分片集群特点
集群中有多个master,每个master保存不同数据
每个master都可以有多个slave节点
master之间通过ping监测彼此健康状态
客户端请求可以访问集群任意节点,最终都会被转发到正确节点
散列插槽
0~16383共16384个插槽会被分配到master节点上,
数据key不是与节点绑定,而是与插槽绑定,redis会根据key的有效部分计算插槽值
- key中包含”{}”,且“{}”中至少包含1个字符,“{}”中的部分是有效部分,可以通过{}来将同一类数据存储到同一个Redis实例中
- key中不包含“{}”,整个key都是有效部分
配置分片集群实例
准备实例和配置
准备实例和配置
IP PORT 角色 192.168.229.128 7001 master 192.168.229.128 7002 master 192.168.229.128 7003 master 192.168.229.128 8001 slave 192.168.229.128 8002 slave 192.168.229.128 8003 slave 创建配置文件redis.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21port 6379
# 开启集群功能
cluster-enabled yes
# 集群的配置文件名称,不需要我们创建,由redis自己维护
cluster-config-file /home/cyx/redis/6379/nodes.conf
# 节点心跳失败的超时时间
cluster-node-timeout 5000
# 持久化文件存放目录
dir /home/cyx/redis/6379
# 绑定地址
bind 0.0.0.0
# 让redis后台运行
daemonize yes
# 注册的实例ip
replica-announce-ip 192.168.229.128
# 保护模式
protected-mode no
# 数据库数量
databases 1
# 日志
logfile /home/cyx/redis/6379/run.log1
2# 执行拷贝
echo 7001 7002 7003 8001 8002 8003 | xargs -t -n 1 cp redis.conf修改配置文件,将其中的6379修改为与所在目录一致
1
2# 同时修改配置文件
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t sed -i 's/6379/{}/g' {}/redis.conf启动/关闭
1
2
3
4
5
6
7
8#同时启动所有redis
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-server {}/redis.conf
#查看redis进程
ps -ef | grep redis
#关闭所有redis进程
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-cli -p {} shutdown
创建集群
集群管理以及集成到了redis-cli中
1
redis-cli --cluster create --cluster-replicas 1 192.168.229.128:7001 192.168.229.128:7002 192.168.229.128:7003 192.168.229.128:8001 192.168.229.128:8002 192.168.229.128:8003
命令说明:
redis-cli --cluster
或者./redis-trib.rb
:代表集群操作命令create
:代表是创建集群--replicas 1
或者--cluster-replicas 1
:指定集群中每个master的副本个数为1,此时节点总数 ÷ (replicas + 1)
得到的就是master的数量。因此节点列表中的前n个就是master,其它节点都是slave节点,随机分配到不同master
查看集群状态
1
redis-cli -p 7001 cluster nodes
使用
添加数据
1
2
3# 打开客户端,-c代表集群操作
redis-cli -c -p 7001
# 之后就可以CRUD了,redis根据key算出的hash值存到对应插槽中
操作集群
查看帮助文档
1
redis-cli --cluster help
添加节点到集群(add-node)
1
2# 添加的节点是没有插槽的
redis-cli --cluster add-node 要添加的节点ip:端口 一个maser节点的ip:端口转移插槽(reshard)
1
2redis-cli --cluster reshard 要分配插槽的Redis实例的ip:端口
# 之后会让输入要分配的插槽数量、从哪个节点移动插槽、跟着提示来就行
故障转移
自动故障转移
出现宕机的节点时,自动提升一个slave为新的master
宕机的节点重新上线时,会变成slave节点
手动故障转移
进入节点的客户端,执行cluster failover命令,这个节点就会称为master节点
RedisTemplate访问集群
和哨兵模式差不多
- 引入redis的starter依赖
- 配置分片集群地址 (就这步有差异)
- 配置读写分离
1 |
|