外观
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工作原理
- Redis主进程执行BGSAVE命令
- 主进程fork()创建子进程
- 子进程遍历内存数据,生成RDB文件
- 子进程完成后通知主进程
- 主进程更新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 yesRDB优缺点
- 优点:文件体积小,恢复速度快,适合备份和灾难恢复
- 缺点:可能丢失最近写入的数据,fork()操作在大数据量时开销大
AOF持久化
AOF(Append Only File)是Redis的日志持久化方式,记录所有写命令。
AOF工作原理
- 客户端发送写命令
- 命令被追加到AOF缓冲区
- 根据同步策略,缓冲区内容被写入AOF文件
- 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 64mbAOF优缺点
- 优点:数据安全性高,可配置不同的同步策略
- 缺点:文件体积大,恢复速度慢
混合持久化
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:查找大keyredis-cli monitor:实时监控命令执行- Prometheus+Grafana:可视化监控
Q5: Redis的存储架构对性能有什么影响?
A5: Redis的存储架构直接影响其性能:
- 内存存储提供高性能访问
- 持久化操作会影响写入性能
- 数据结构和编码方式影响内存使用和访问速度
- 内存淘汰策略影响系统稳定性
- 合理的存储架构设计是Redis高性能的关键
