第六章:Redis分布式缓存

Redis分布式缓存架构核心解决方案

摘要:针对单机Redis的四大核心问题,分布式架构提供了完整解决方案:1)通过RDB和AOF持久化机制解决数据丢失问题,RDB适合快速恢复,AOF保障数据安全;2)采用主从复制实现读写分离,提升并发能力,支持全量/增量同步;3)基于哨兵机制实现自动故障转移,确保高可用性,包含监控、选举、切换全流程;4)通过分片集群扩展存储容量,采用哈希槽机制实现数据分布。生产环境建议综合运用多种技术,主从+哨兵适合中小规模,分片集群应对海量数据,同时需优化持久化策略、网络配置和内存管理。

概述

单机Redis存在四大核心问题,通过分布式缓存架构可有效解决:

  1. 数据丢失问题 - 持久化机制保障

  2. 并发能力有限 - 主从读写分离提升

  3. 故障恢复困难 - 哨兵自动故障转移

  4. 存储容量限制 - 分片集群扩展

一、Redis持久化机制

1.1 RDB持久化(Redis Database Backup)

1.1.1 执行触发时机

主动触发:

复制代码
# 控制台

# 同步执行(阻塞主进程,生产环境慎用)
save

# 异步执行(后台fork子进程)
bgsave

自动触发配置:

复制代码
# properties配置文件

# redis.conf配置
save 900 1      # 900秒内至少1次修改
save 300 10     # 300秒内至少10次修改
save 60 10000   # 60秒内至少10000次修改

其他触发:

  • Redis正常关闭时自动执行save

  • 主从复制时,主节点自动触发bgsave

1.1.2 RDB配置参数
复制代码
# properties配置文件

# RDB文件名称
dbfilename dump.rdb

# 文件保存目录
dir ./

# 是否压缩(建议关闭,CPU换磁盘不划算)
rdbcompression no

# 保存时错误是否继续工作
stop-writes-on-bgsave-error yes
1.1.3 RDB执行原理

基于写时复制(Copy-on-Write)技术:

text

复制代码
1. 主进程fork()创建子进程
2. 子进程共享父进程内存空间
3. 父进程继续处理客户端请求
4. 子进程遍历内存数据写入RDB文件
5. 父进程修改数据时复制内存页副本
6. 子进程完成写入后替换旧RDB文件
1.1.4 RDB优缺点分析

优点:

  • 二进制紧凑格式,恢复速度快

  • 适合备份和灾难恢复

  • 最大化Redis性能(fork进程开销相对固定)

缺点:

  • 数据安全性较低(可能丢失最后一次保存后的数据)

  • fork过程内存占用翻倍(大数据量时影响性能)

  • 保存间隔期间故障会丢失数据

1.2 AOF持久化(Append Only File)

1.2.1 AOF配置详解
java 复制代码
# properties配置文件

# 开启AOF
appendonly yes

# AOF文件名
appendfilename "appendonly.aof"

# 同步策略(三选一)
appendfsync always      # 每个写命令立即同步(最安全,性能差)
appendfsync everysec    # 每秒同步一次(推荐,平衡方案)
appendfsync no          # 由操作系统决定(最快,最不安全)
1.2.2 AOF重写机制

触发条件:

java 复制代码
# properties配置文件

# 当前AOF文件大小超过上次重写大小的100%时触发
auto-aof-rewrite-percentage 100

# AOF文件最小达到64MB才触发重写
auto-aof-rewrite-min-size 64mb

手动触发:

java 复制代码
# 控制台

bgrewriteaof  # 后台重写AOF文件

重写原理:

text

复制代码
原始命令:set name jack → set name tom → set name alice
重写后:set name alice(只保留最终状态)
1.2.3 AOF优缺点

优点:

  • 数据安全性高(最多丢失1秒数据)

  • 可读性好,便于分析

  • 支持误操作恢复(删除错误命令)

缺点:

  • 文件体积大,恢复速度慢

  • 写入性能比RDB略差

  • 重写期间可能阻塞服务

1.3 RDB与AOF对比决策

特性 RDB AOF
数据安全性 可能丢失几分钟数据 最多丢失1秒数据
恢复速度 慢(需重新执行命令)
文件大小 小(二进制压缩) 大(文本格式)
对性能影响 保存时影响大 持续写入影响小
适用场景 备份、灾难恢复 数据安全性要求高

生产建议:同时开启两种持久化

properties配置文件

复制代码
# Redis重启时优先加载AOF文件
# 定期用RDB做冷备份

二、Redis主从复制架构

2.1 主从复制原理详解

2.1.1 全量同步流程
java 复制代码
1. slave发送psync ? -1 请求同步
2. master判断slave为首次连接,执行bgsave
3. master发送RDB文件给slave
4. slave清空旧数据,加载RDB
5. master将RDB期间的命令存入repl_backlog
6. master持续发送repl_backlog中的命令
7. slave执行命令,与master保持同步

关键概念:

  • Replication ID:数据集唯一标识,主从相同表示同一数据集

  • offset:复制偏移量,记录命令位置

2.1.2 增量同步机制

repl_backlog工作原理:

java 复制代码
# properties配置文件

# 环形缓冲区配置
repl-backlog-size 1mb    # 缓冲区大小
repl-backlog-ttl 3600    # 缓冲区保留时间(秒)

同步判断逻辑:

python 复制代码
# python环境
if slave.replid != master.replid:
    # 首次连接,执行全量同步
    do_full_sync()
elif slave.offset in master.backlog:
    # offset在缓冲区,执行增量同步
    do_partial_sync(slave.offset)
else:
    # offset已丢失,执行全量同步
    do_full_sync()
2.1.3 主从同步优化策略
  1. 无磁盘复制(避免全量同步IO)

    python 复制代码
    # properties配置文件
    
    repl-diskless-sync yes
    repl-diskless-sync-delay 5
  2. 合理配置缓冲区

    python 复制代码
    # properties配置文件
    
    # 根据写入量和网络情况调整
    repl-backlog-size 512mb
  3. 级联复制减少主节点压力

    python 复制代码
    主节点 → 从节点1 → 从节点2

2.2 主从配置实践

2.2.1 命令行配置
python 复制代码
# 控制台

# 在从节点执行
redis-cli -p 6380
SLAVEOF 127.0.0.1 6379

# 查看复制信息
INFO replication
2.2.2 配置文件设置
python 复制代码
# properties配置文件

# 从节点配置
slaveof 127.0.0.1 6379
slave-read-only yes
masterauth <password>  # 如果主节点有密码

三、Redis哨兵高可用方案

3.1 哨兵核心功能

3.1.1 监控机制

心跳检测:

  • 每隔1秒向所有节点发送PING命令

  • 主观下线:单个哨兵认为节点不可用

  • 客观下线:超过quorum数量的哨兵认为节点不可用

配置示例:

python 复制代码
# properties配置文件

# sentinel.conf
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
3.1.2 故障转移流程
python 复制代码
1. 发现master客观下线
2. 选举领头哨兵(Raft算法)
3. 选择新master(按优先级、offset、runid)
4. 执行slaveof no one提升新master
5. 其他slave切换至新master
6. 旧master恢复后作为slave加入

选举规则优先级:

  1. 断开时间小于阈值(down-after-milliseconds * 10)

  2. slave-priority值越小优先级越高(0表示不参与选举)

  3. offset值越大优先级越高(数据越新)

  4. runid越小优先级越高

3.2 Spring Boot集成哨兵

3.2.1 依赖配置
XML 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
3.2.2 配置文件
python 复制代码
# yaml配置文件

spring:
  redis:
    sentinel:
      master: mymaster
      nodes:
        - 192.168.1.101:26379
        - 192.168.1.102:26379
        - 192.168.1.103:26379
3.2.3 读写分离配置
java 复制代码
@Configuration
public class RedisConfig {
    
    @Bean
    public LettuceClientConfigurationBuilderCustomizer customizer() {
        return builder -> builder.readFrom(ReadFrom.REPLICA_PREFERRED);
    }
}

读取策略选项:

  • MASTER:只从主节点读

  • MASTER_PREFERRED:优先主节点,不可用则从节点

  • REPLICA:只从从节点读

  • REPLICA_PREFERRED:优先从节点,不可用则主节点

四、Redis分片集群

4.1 集群架构设计

4.1.1 集群特点
  • 多个master节点,每个存储不同数据

  • 每个master可有多个slave节点

  • 数据分片存储,解决海量数据问题

  • 支持水平扩展和高并发写

4.1.2 散列插槽机制

插槽分配:

java 复制代码
# 控制台
# 查看集群节点和插槽分配
redis-cli -p 7001 cluster nodes

key路由规则:

python 复制代码
# python环境

def slot_calculation(key):
    # 如果key包含{},则只计算{}内的部分
    if '{' in key and '}' in key:
        hash_key = key[key.find('{')+1:key.find('}')]
    else:
        hash_key = key
    
    # CRC16计算哈希值后对16384取模
    return crc16(hash_key) % 16384

应用技巧:

python 复制代码
# 控制台
# 同一类数据固定存储(使用相同hash tag)
set {user:1000}:name "张三"
set {user:1000}:age 25
set {user:1000}:email "zhangsan@example.com"

4.2 集群管理操作

4.2.1 集群伸缩操作

添加新节点:

python 复制代码
# 控制台
# 启动新实例
redis-server 7004/redis.conf

# 添加节点到集群
redis-cli --cluster add-node 192.168.1.104:7004 192.168.1.101:7001

# 查看节点状态(新增节点无插槽)
redis-cli -p 7001 cluster nodes

重新分配插槽:

python 复制代码
# 控制台
# 重新分配插槽
redis-cli --cluster reshard 192.168.1.101:7001

# 交互式操作流程:
# 1. 输入要移动的插槽数量(如3000)
# 2. 输入接收节点ID
# 3. 输入源节点ID(或all从所有节点平均移动)
# 4. 输入yes确认
4.2.2 故障转移处理

自动故障转移:

python 复制代码
# 控制台

# 停止一个master节点
redis-cli -p 7002 shutdown

# 观察自动切换过程
redis-cli -p 7001 cluster nodes

手动故障转移(维护时使用):

python 复制代码
# 控制台

# 连接到要从节点
redis-cli -p 8001

# 执行手动故障转移
CLUSTER FAILOVER [FORCE|TAKEOVER]

故障转移模式:

  • 默认模式:完整流程,保证数据一致性

  • FORCE模式:跳过一致性检查,快速切换

  • TAKEOVER模式:强制切换,无视其他节点意见

4.3 Spring Boot集成集群

python 复制代码
# yaml配置文件

spring:
  redis:
    cluster:
      nodes:
        - 192.168.1.101:7001
        - 192.168.1.101:7002
        - 192.168.1.101:7003
        - 192.168.1.101:8001
        - 192.168.1.101:8002
        - 192.168.1.101:8003
      max-redirects: 3  # 最大重定向次数

五、生产环境最佳实践

5.1 持久化策略建议

python 复制代码
# properties配置文件

# 综合配置示例
# 1. 同时开启RDB和AOF
appendonly yes
appendfsync everysec

# 2. RDB配置为低频高量
save 3600 1000
save 300 100
save 60 10000

# 3. AOF自动重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 256mb

# 4. 禁用AOF重写期间追加
no-appendfsync-on-rewrite yes

5.2 主从复制优化

python 复制代码
# properties配置文件

# 主节点配置
repl-backlog-size 512mb
repl-backlog-ttl 3600
min-slaves-to-write 1
min-slaves-max-lag 10

# 从节点配置
slave-serve-stale-data yes
slave-read-only yes

5.3 哨兵配置要点

python 复制代码
# properties配置文件

# 哨兵基础配置
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

# 生产环境建议
sentinel auth-pass mymaster <password>
sentinel notification-script mymaster /path/to/script.sh

5.4 集群运维建议

  1. 容量规划:预留30%内存用于bgsave和集群管理

  2. 监控告警:监控节点状态、内存使用、网络延迟

  3. 备份策略:定期RDB备份到异地

  4. 升级方案:先升级从节点,再手动故障转移升级主节点

六、故障排查与性能调优

6.1 常见问题排查

主从同步失败:

python 复制代码
# 控制台
# 检查主从状态
INFO replication

# 查看复制错误
redis-cli -p 6380 DEBUG REPLICATION

# 检查网络连通性
redis-cli -p 6379 PING

哨兵无法故障转移:

python 复制代码
# 控制台

# 查看哨兵日志
tail -f /var/log/redis/sentinel.log

# 检查仲裁数量配置
redis-cli -p 26379 SENTINEL GET-master-addr-by-name mymaster

集群节点故障:

python 复制代码
# 控制台

# 检查集群健康状态
redis-cli --cluster check 192.168.1.101:7001

# 修复故障节点
redis-cli --cluster fix 192.168.1.101:7001

6.2 性能优化参数

python 复制代码
# properties配置文件

# 网络优化
tcp-keepalive 300
timeout 0

# 内存优化
maxmemory-policy volatile-lru
maxmemory-samples 5

# 持久化优化
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes

总结对比表

方案 数据安全 可用性 扩展性 适用场景
单机+持久化 开发测试、小数据量
主从复制 读扩展 读多写少,允许短暂不可用
哨兵模式 读扩展 高可用要求,自动故障转移
分片集群 读写扩展 海量数据,高并发读写

架构选择建议:

  1. 中小规模:主从+哨兵,满足大部分生产需求

  2. 大数据量:分片集群,支持水平扩展

  3. 混合架构:集群内部分片,分片内部主从+哨兵

相关推荐
笨蛋不要掉眼泪4 小时前
Redis主从复制:原理、配置与实战演示
前端·redis·bootstrap·html
晓13134 小时前
第七章:Redis高级最佳实践详解
redis·分布式·缓存
jiunian_cn6 小时前
【Redis】list数据类型相关指令
数据库·redis·list
Big Cole6 小时前
PHP面试题(Redis核心知识篇)
开发语言·redis·php
TracyCoder1236 小时前
Redis分布式限流技术原理与实战
redis
小北方城市网6 小时前
MongoDB 分布式存储与查询优化:从副本集到分片集群
java·spring boot·redis·分布式·wpf
xxxmine19 小时前
redis学习
数据库·redis·学习
qq_54702617919 小时前
Redis 常见问题
数据库·redis·mybatis
知识即是力量ol20 小时前
基于 Redis 实现白名单,黑名单机制详解及应用场景
数据库·redis·缓存