一、Redis 内存回收的整体架构
Redis 是一个 内存数据库,所有键值都存放在 RAM 中。
为了避免无限增长导致 OOM(Out Of Memory),Redis 有三大类内存回收机制:
1. 键过期删除策略(主动回收)
- 惰性删除(Lazy Deletion)
- 定期删除(Tuned Scanning)
2. 内存淘汰策略(当内存达到最大值 maxmemory)
- noeviction / allkeys-* / volatile-* 系列
3. 内存碎片与 jemalloc 管理(内存再利用)
- jemalloc arena 管理
- active defrag(主动碎片整理)
这三者共同对 Redis 内存进行回收和优化。
二、键过期删除(Expires)
Redis 支持给 key 设置 TTL(time-to-live)。
EXPIRE key 10
SET key value EX 10
Redis 的过期键删除不是精确实时触发,而是采用三种机制组合:
1. 惰性删除(Lazy Deletion)
触发时机:
- 当客户端访问某个 key
- Redis 检查它是否已经过期
- 过期 → 立即删除
示例:
GET key
→ 发现 key 已过期 → 删除并返回 nil
优点:
- 简单、高效
- 不访问不过期,不浪费 CPU
缺点:
- 如果 key 很久不被访问
- 会一直占用内存(内存泄漏风险)
所以 Redis 还必须搭配第二种机制。
2. 定期删除(Active Expire Cycle)
Redis 每 100ms(server.hz 参数控制)随机抽取部分带过期时间的 key:
流程:
- 随机扫描一部分 db.expires 字典
- 删除其中已经过期的 key
- 如果过期比例 > 25%,继续扫描(最多执行 25ms)
优点:
- 避免过期键长期堆积
- 平衡 CPU 占用
缺点:
- 不是实时、高精度的删除
- 大量过期键可能延迟删除
3. 主动删除 + 从节点同步
在执行命令期间,如果命令涉及访问过期 key:
- 主线程执行惰性删除
- 命令传播到从节点和 AOF 时也写入 DEL 操作
三、内存淘汰策略(maxmemory 触发)
当 Redis 达到 maxmemory 时,就会触发内存淘汰策略。
配置:
maxmemory 2gb
maxmemory-policy allkeys-lru
Redis 内置 8 种策略:
1. 不淘汰
● noeviction
内存满时写命令(SET/LPUSH/ZADD)直接报错。
2. 只淘汰带过期时间的键(volatile-*)
| 策略 | 说明 |
|---|---|
| volatile-lru | 淘汰最近最少使用的 expire key |
| volatile-lfu | 淘汰访问最少的 expire key |
| volatile-ttl | 淘汰剩余生存时间最短的 key |
| volatile-random | 随机淘汰一个 expire key |
如果没有带 TTL 的 key → 和 noeviction 一样报错。
3. 淘汰所有键(allkeys-*)
| 策略 | 说明 |
|---|---|
| allkeys-lru | 淘汰最近最少使用的 key |
| allkeys-lfu | 淘汰访问最少的 key(Redis 4+) |
| allkeys-random | 随机淘汰一个 key |
企业生产最常用:
allkeys-lru
allkeys-lfu(访问热点分布更均衡)
四、Redis 的内存分配器:jemalloc
Redis 默认使用 jemalloc 来管理内存。
jemalloc 特点:
- 多个 arena,减少锁竞争
- 对小块内存管理更高效
- 减少内存碎片
- 速度快(Redis 高性能关键之一)
Redis 里每个 key/结构体 要走 jemalloc 的分配逻辑。
四、内存碎片问题
Redis 内存碎片率:
info memory → mem_fragmentation_ratio
当碎片率 > 1.5 或 2 时可能需要处理。
Redis 支持主动碎片整理:
active-defrag yes
作用:
- 后台线程合并碎片块
- 迁移 key 的内存布局
- 减少物理内存占用
适用于高更新写 load 的业务。
五、Redis 内存回收的整体流程图

六、实际场景中的内存回收案例
情况 1:大量 key 同时过期(如 0 点定时刷新)
效果:
- 惰性删除无法及时回收
- 定期扫描也跟不上
- Redis 内存激增
解决:
- 设置随机 TTL(打散过期时间)
- 使用 expire 命令 + 随机偏移
情况 2:大量数据更新导致碎片暴涨
解决:
active-defrag yes
适合 key 更新频繁的系统(订单系统、排行榜系统)。
情况 3:内存爆满导致频繁淘汰、QPS 急剧下降
解决:
- 分析 key 大小(大 key 拆分)
- 调整 maxmemory-policy
- 提高 Redis 内存
- 使用 Redis Cluster 分片
七、面试高频问题(含标准答案)
1. Redis 的过期删除策略是什么?
答:惰性删除 + 定期删除 双策略。
2. Redis 内存淘汰策略有哪些?
8 种:
- noeviction
- volatile-lru / lfu / ttl / random
- allkeys-lru / lfu / random
3. 为什么 Redis 采用定期删除而不是主动删除?
因为主动删除是 O(n) 扫描,会阻塞主线程。
4. LRU 与 LFU 区别?
- LRU:最近最少使用
- LFU:访问次数最少
LFU 更适合热点数据分布不均的业务。
5. Redis 为什么使用 jemalloc?
- 更快
- 内存碎片更少
- 多线程 arena 更适合 Redis 高并发
6. active-defrag 是如何工作的?
后台线程迁移 key 内部结构,使碎片合并。
八、总结(背诵版)
Redis 内存回收 = 过期清理 + 内存淘汰 + 内存碎片整理
- 过期键:惰性删除 + 定期删除
- 内存限制:maxmemory-policy
- 内存管理:jemalloc
- 碎片修复:active-defrag
- 大 key 问题:拆分 + 批量删除
Redis 内存管理体系既高效又安全,是持久高性能的重要基础。
713

被折叠的 条评论
为什么被折叠?



