Skip to content

Redis 存储架构

内存存储机制

数据结构与内存编码

Redis支持多种数据类型,每种类型都有对应的内存编码方式:

字符串(String)

  • raw:适用于长字符串(大于39字节)
  • embstr:适用于短字符串(小于等于39字节),连续内存分配
  • int:适用于整数值,直接存储为long类型

列表(List)

  • ziplist:适用于元素数量少且小的列表
  • linkedlist:适用于元素数量多或大的列表
  • quicklist(Redis 3.2+):结合ziplist和linkedlist的优点,平衡内存使用和性能

哈希(Hash)

  • ziplist:适用于字段数量少且小的哈希
  • hashtable:适用于字段数量多或大的哈希

集合(Set)

  • intset:适用于元素都是整数且数量少的集合
  • hashtable:适用于元素包含字符串或数量多的集合

有序集合(ZSet)

  • ziplist:适用于元素数量少且小的有序集合
  • skiplist:适用于元素数量多或大的有序集合
  • listpack(Redis 5.0+):优化的压缩列表实现,替代部分ziplist使用

内存分配与管理

内存分配器

  • jemalloc:默认内存分配器,高效的内存分配策略
  • tcmalloc:Google开发的内存分配器,适合多线程环境
  • libc malloc:标准C库分配器,兼容性好但性能较低

内存管理命令

  • MEMORY USAGE key:查看单个键的内存使用
  • MEMORY STATS:查看详细内存统计信息
  • MEMORY PURGE:释放内存分配器未使用的内存
  • CONFIG SET maxmemory:设置最大内存限制

内存淘汰策略

当内存使用达到上限时,Redis会根据配置的淘汰策略删除部分键:

淘汰策略分类

  • volatile-lru:从设置了过期时间的键中,删除最近最少使用的
  • volatile-lfu:从设置了过期时间的键中,删除最不经常使用的
  • volatile-ttl:从设置了过期时间的键中,删除剩余TTL最短的
  • volatile-random:从设置了过期时间的键中,随机删除
  • allkeys-lru:从所有键中,删除最近最少使用的
  • allkeys-lfu:从所有键中,删除最不经常使用的
  • allkeys-random:从所有键中,随机删除
  • noeviction:不删除键,返回错误(默认策略)

数据持久化机制

RDB持久化

RDB(Redis Database)是Redis的快照持久化方式。

RDB工作原理

  1. Redis主进程执行BGSAVE命令
  2. 主进程fork()创建子进程
  3. 子进程遍历内存数据,生成RDB文件
  4. 子进程完成后通知主进程
  5. 主进程更新RDB文件元数据

RDB配置参数

# 自动触发RDB的条件
save 900 1    # 900秒内至少1个键被修改
save 300 10   # 300秒内至少10个键被修改
save 60 10000 # 60秒内至少10000个键被修改

# RDB文件配置
dbfilename dump.rdb
dir /var/lib/redis

# RDB压缩
trdbcompression yes

RDB优缺点

  • 优点:文件体积小,恢复速度快,适合备份和灾难恢复
  • 缺点:可能丢失最近写入的数据,fork()操作在大数据量时开销大

AOF持久化

AOF(Append Only File)是Redis的日志持久化方式,记录所有写命令。

AOF工作原理

  1. 客户端发送写命令
  2. 命令被追加到AOF缓冲区
  3. 根据同步策略,缓冲区内容被写入AOF文件
  4. AOF文件定期重写,减少文件大小

AOF配置参数

# 启用AOF
appendonly yes

# AOF文件名
appendfilename appendonly.aof

# AOF同步策略
appendfsync everysec  # 每秒同步(推荐)
# appendfsync always  # 每次写同步
# appendfsync no      # 由操作系统决定

# AOF重写配置
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

AOF优缺点

  • 优点:数据安全性高,可配置不同的同步策略
  • 缺点:文件体积大,恢复速度慢

混合持久化

Redis 4.0引入混合持久化,结合RDB和AOF的优点。

混合持久化工作原理

  • AOF文件头部包含RDB格式的快照
  • AOF文件后续包含增量写命令
  • 恢复时先加载RDB快照,再执行AOF命令

混合持久化配置

# 启用混合持久化(Redis 4.0+)
aof-use-rdb-preamble yes

混合持久化优缺点

  • 优点:文件体积小,恢复速度快,数据安全性高
  • 缺点:需要Redis 4.0+版本支持

存储引擎优化

内存优化策略

数据结构优化

  • 选择合适的数据类型:根据业务场景选择最适合的数据类型
  • 使用ziplist/intset编码:小数据量时自动使用更紧凑的编码
  • 避免大key:将大key拆分为多个小key,减少内存使用和命令执行时间

内存压缩

  • Redis 6.0+:支持结构化数据压缩,如哈希、列表等
  • Redis Modules:通过模块扩展,支持更多压缩算法

过期键清理

  • 惰性删除:访问键时检查是否过期,过期则删除
  • 定期删除:定期扫描一部分键,删除过期的键
  • 配置合理的过期时间:避免内存中积累大量过期键

持久化优化

RDB优化

  • 合理配置save参数:根据业务需求调整自动触发条件
  • 禁用自动快照:在高写入场景下,考虑手动触发BGSAVE
  • 使用外部备份工具:如redis-backup,减少Redis主进程负担

AOF优化

  • 使用everysec同步策略:平衡性能和数据安全性
  • 合理配置重写参数:避免频繁重写影响性能
  • 定期检查AOF文件完整性:使用redis-check-aof工具

存储架构的演变

Redis 1.0-2.8

  • 基本的内存存储和RDB持久化
  • 引入AOF持久化
  • 简单的内存管理机制

Redis 3.0

  • 引入Redis Cluster,支持分布式存储
  • 改进内存管理,优化内存使用
  • 引入quicklist数据结构,优化列表存储

Redis 4.0

  • 引入混合持久化
  • 改进RDB格式,支持更大数据集
  • 引入模块系统,支持存储引擎扩展

Redis 5.0

  • 引入listpack数据结构,替代部分ziplist使用
  • 改进AOF重写算法,减少CPU占用
  • 支持RESP3协议,优化客户端通信

Redis 6.0

  • 引入多线程I/O,提高网络处理能力
  • 支持结构化数据压缩
  • 改进内存管理,减少内存碎片

Redis 7.0

  • 引入RDB版本7,支持更大数据集和更快恢复
  • 改进AOF重写机制,减少磁盘I/O
  • 支持更多数据类型的内存优化

常见问题(FAQ)

Q1: Redis的内存使用过高怎么办?

A1: 可以采取以下措施:

  • 检查是否存在内存泄漏
  • 优化数据结构,减少内存占用
  • 配置合理的内存淘汰策略
  • 考虑使用Redis Cluster进行水平扩展
  • 定期清理过期键

Q2: RDB和AOF应该选择哪种持久化方式?

A2: 推荐使用混合持久化(Redis 4.0+),结合RDB和AOF的优点。如果必须选择一种:

  • 对数据安全性要求高:选择AOF
  • 对恢复速度要求高:选择RDB
  • 数据量大:选择RDB

Q3: 为什么Redis的fork()操作会导致阻塞?

A3: fork()操作在复制进程内存页表时会阻塞主进程,阻塞时间取决于内存大小和系统性能。可以采取以下措施减少影响:

  • 配置合理的内存大小
  • 使用小内存实例,通过Redis Cluster扩展
  • 在低峰期执行BGSAVE或BGREWRITEAOF命令
  • 使用Redis 4.0+,改进了fork()机制

Q4: 如何监控Redis的存储使用情况?

A4: 可以使用以下命令和工具:

  • INFO memory:查看内存使用统计
  • INFO persistence:查看持久化状态
  • redis-cli --bigkeys:查找大key
  • redis-cli monitor:实时监控命令执行
  • Prometheus+Grafana:可视化监控

Q5: Redis的存储架构对性能有什么影响?

A5: Redis的存储架构直接影响其性能:

  • 内存存储提供高性能访问
  • 持久化操作会影响写入性能
  • 数据结构和编码方式影响内存使用和访问速度
  • 内存淘汰策略影响系统稳定性
  • 合理的存储架构设计是Redis高性能的关键