【分布式缓存】Redis持久化和集群部署攻略
分布式缓存是将数据存储在多个节点上的缓存系统,旨在提高应用的性能和可扩展性
文字目录
一、持久化
1.1 RDB
1.2 AOF
1.3 混合持久化
二、主从同步
2.1 主从搭建
2.2 数据同步原理
三、哨兵集群
3.1 哨兵部署
3.2 项目集成
四、分片集群
4.1 分片部署
一、持久化
1.1 RDB
英文全称:Redis Database Backup,简单来说是一种redis的内存数据备份到磁盘的机制。在指定时间间隔内,将内存中的数据集以二进制压缩快照保存到磁盘。
默认是开启的,也可在redis.conf的配置文件配置下面内容:
# 设置RDB快照保存间隔
save 5 1
# 900秒内至少1个key变化
save 900 1
# 300秒内至少10个key变化
save 300 10
# RDB文件名
dbfilename testDump.rdb
# RDB目录
dir /data
# 持久化出错时是否停止写入
stop-writes-on-bgsave-error yes
# 是否压缩 RDB 文件
rdbcompression yes
# 是否检查 RDB 文件校验和
rdbchecksum yes

1.2 AOF
英文全称:Append Only File仅追加文件的缩写,通过记录所有的写操作命令实现的
AOF的同步策略:

redis.conf的配置文件配置下面内容:
# 启动AOF
appendonly yes
# 同步策略,每秒一次
appendfsync everysec
# AOF文件名
appendfilename "testAppendOnly.aof"
# AOF目录
dir /data
# 自动重写触发条件
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 启用重写期间同步
no-appendfsync-on-rewrite no

1.3 混合持久化
在redis4以后支持结合二者持久化方案,上面的MP-AOF就是一种体现。
aof-use-rdb-preamble yes
二、主从同步
2.1 主从搭建
这里依旧是我们的老朋友docker多实例部署模拟集群环境。
部分docker-compose.yml文件参考:
redis:image: redis:7-alpinecontainer_name: my-redis-publicrestart: alwaysports:- "6379:6379"volumes:- /opt/redis/redis.conf:/usr/local/etc/redis/redis.conf- /opt/redis/ssl:/opt/redis/ssl- /opt/redis_data:/datacommand: ["redis-server", "/usr/local/etc/redis/redis.conf"]networks:- public-netredis-v2:image: redis:7-alpinecontainer_name: my-redis-public-v2restart: alwaysports:- "6380:6379"volumes:- /opt/redis/redis-v2.conf/redis.conf:/usr/local/etc/redis/redis.conf- /opt/redis/ssl:/opt/redis/ssl- /opt/redis_v2_data:/data# 通过slaveof实现主从复制 command: ["redis-server", "/usr/local/etc/redis/redis.conf"]networks:- public-netredis-v3:image: redis:7-alpinecontainer_name: my-redis-public-v3restart: alwaysports:- "6381:6379"volumes:- /opt/redis/redis-v3.conf/redis.conf:/usr/local/etc/redis/redis.conf- /opt/redis/ssl:/opt/redis/ssl- /opt/redis_v3_data:/data# 通过slaveof实现主从复制 command: ["redis-server", "/usr/local/etc/redis/redis.conf"]networks:- public-net
主节点redis的配置文件可以直修改密码即可,其余无需多余配置
从节点的redis-v2和redis-v3的配置参考如下:
# 设置密码
requirepass 123
protected-mode no
# 重命名危险命令,使其无法被轻易调用
rename-command FLUSHALL "CMD_FLUSHALL_DISABLED_$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16)"
rename-command FLUSHDB "CMD_FLUSHDB_DISABLED_$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16)"
rename-command KEYS "CMD_KEYS_DISABLED_$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16)"
rename-command CONFIG "CMD_CONFIG_DISABLED_$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16)"appendonly no
# 指定主节点
replicaof redis 6379
# 与主节点密码一致
masterauth 111111111111111111111
进入从节点v3内部,可以获取到数据,但是不可写。至此模拟的主从搭建完成

2.2 数据同步原理

三、哨兵集群
3.1 哨兵部署
mkdir -p /opt/redis/sentinel/{conf,data1,data2,data3}
touch ./conf/sentinel1.conf
port 26379
dir "/data"
sentinel monitor mymaster 192.168.18.131 6379 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 10000
sentinel deny-scripts-reconfig yes
protected-mode no
echo ../conf/sentinel2.conf ../conf/sentinel3.conf | xargs -t -n 1 cp ./sentinel1.conf
sed -e -i 's/26379/26380/g' ./sentinel2.conf
sed -e -i 's/26379/26381/g' ./sentinel3.conf
sentinel1:image: redis:7-alpinecontainer_name: redis-sentinel-1restart: alwaysports:- "26379:26379"volumes:- /opt/redis/sentinel/conf/sentinel1.conf:/etc/redis/sentinel.conf- /opt/redis/sentinel/data1:/datacommand: ["redis-sentinel", "/etc/redis/sentinel.conf"]networks:- public-netsentinel2:image: redis:7-alpinecontainer_name: redis-sentinel-2restart: alwaysports:- "26380:26380"volumes:- /opt/redis/sentinel/conf/sentinel2.conf:/etc/redis/sentinel.conf- /opt/redis/sentinel/data2:/datacommand: ["redis-sentinel", "/etc/redis/sentinel.conf"]networks:- public-netsentinel3:image: redis:7-alpinecontainer_name: redis-sentinel-3restart: alwaysports:- "26381:26381"volumes:- /opt/redis/sentinel/conf/sentinel3.conf:/etc/redis/sentinel.conf- /opt/redis/sentinel/data3:/datacommand: ["redis-sentinel", "/etc/redis/sentinel.conf"]networks:- public-net
通过logs看到打印主从信息,即代表哨兵搭建成功

踩坑记录:
1.密码没有正确配置,2.sentinel的地址写为了容器,但是不互通,3.禁用了config命令

3.2 项目集成
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
# Redis Sentinel 配置
# Redis 主节点名称
spring.redis.sentinel.master=mymaster
# Sentinel 节点地址
spring.redis.sentinel.nodes=120.27.236.84:26379,120.27.236.84:26380,120.27.236.84:26381
# Redis 数据库索引(默认为 0)
spring.redis.database=0
# Redis 连接超时时间
spring.redis.timeout=3000
# Redis 连接池配置
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
@Beanpublic LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer() {return clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA);}
四、分片集群
4.1 分片部署
搭建图示如下,一主一从构建分片集群

具体搭建步骤如下,这里演示的是直接部署在服务器上,笔者不想去折腾docker部署分片集群了
创建对应的文件夹
mkdir 7001 7002 7003 8001 8002 8003
创建redis的配置文件
vim 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.150.101
# 保护模式
protected-mode no
# 数据库数量
databases 1
# 日志
logfile /tmp/6379/run.log
批量拷贝
echo 7001 7002 7003 8001 8002 8003 | xargs -t -n 1 cp redis.conf
修改文件配置的地址内容
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t sed -i 's/6379/{}/g' {}/redis.conf
安装redis环境(如果有则忽略,直接启动即可)
yum install -y gcc tcl
上传redis官网压缩包到指定目录

解压包
tar -xzf redis-6.2.4.tar.gz
进入目录
cd redis-6.2.4.tar.gz
编译和安装
make && make install
启动所有redis服务
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-server {}/redis.conf
查看服务运行状态
ps -ef | grep redis

关闭所有redis进程(了解)
ps -ef | grep redis | awk '{print $2}' | xargs kill
创建集群
redis-cli --cluster create --cluster-replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:8001 127.0.0.1:8002 127.0.0.1:8003
命令解释:replicas等于1,说明集群中的每个主节的副本个数都是1,同时主节点数等于 节点总数 ÷ (replicas数 + 1),前n个结果是主节点,其余随机分配到不同主节点。

查看集群状态
redis-cli -p 7001 cluster nodes
操作集群(注意携带-c)
redis-cli -c -p 7001

可以观察到在写数据时,会对键key去进行计算获取对应的插槽,依据插槽去写到对应的节点
模拟7002故障转移
redis-cli -p 7002 shutdown
redis-cli -p 7001 cluster nodes


