Redis 内存管理
1. Redis 给缓存数据设置过期时间的作用
给缓存数据设置过期时间(TTL, Time-To-Live)有以下几个重要作用:
(1) 自动释放内存
- 避免缓存数据无限增长,导致 Redis 内存溢出。
- 例如,在 会话管理、短连接信息、临时令牌 等场景下,设置过期时间可以自动清理数据,避免占用大量内存。
(2) 提高缓存的实时性
- 设置较短的 TTL 让数据 保持新鲜,保证用户获取的是最新的数据。
- 例如,热点新闻、秒杀活动商品库存,需要定期更新。
(3) 限制数据的生命周期
- 适用于 验证码、用户 Token 等数据,超时后自动失效,提高安全性。
- 例如,验证码有效期 5 分钟,超时后自动删除,防止恶意重复使用。
(4) 提高缓存命中率
- 如果数据频繁变化,不设置过期时间,可能导致大量 冷数据 长期占用内存,影响缓存命中率。
- 通过 TTL 控制数据生命周期,保证 Redis 主要存储热点数据。
2. Redis 是如何判断数据是否过期的?
Redis 通过 两种方式 判断数据是否过期:
(1) 访问 Key 时检查(惰性删除)
- **机制:**当客户端访问一个 Key(如 GET key)时,Redis 检查其过期时间:
- 如果 Key 已过期,立即删除,并返回
nil
或默认值。 - 如果 Key 未过期,则正常返回数据。
- 如果 Key 已过期,立即删除,并返回
- 优点:减少 CPU 资源占用,仅对访问的数据进行检查。
- 缺点:如果一个 Key 长期不被访问,即使已经过期,也不会被删除,可能导致 内存占用过高。
(2) 定期扫描过期 Key(定期删除)
- **机制:**Redis 每 100ms 进行一次过期检查:
- 随机抽取部分 Key(默认 20 个)。
- 检查是否过期,如果过期就删除。
- 如果删除的 Key 超过 25%(默认阈值),则继续下一轮检查,避免过期 Key 堆积。
- 优点:可以主动清理一部分过期数据,减少内存占用。
- 缺点:无法保证所有过期 Key 及时删除,仍可能导致部分过期数据滞留。
3. Redis 过期 Key 的删除策略
Redis 采用 三种删除策略 结合使用,以平衡 性能 和 内存占用。
删除策略 | 触发时机 | 优点 | 缺点 |
---|---|---|---|
惰性删除 | 访问 Key 时检查 | CPU 资源占用低,只检查访问的数据 | 冷数据不会被清理,可能导致内存占满 |
定期删除 | 每 100ms 扫描部分 Key | 主动清理一部分过期 Key,避免过期数据堆积 | 无法清理所有过期 Key,仍可能占用大量内存 |
内存淘汰(Eviction) | 内存满时触发 | 确保 Redis 可用,释放空间给新数据 | 可能删除热点数据,影响缓存命中率 |
4. Redis 的内存淘汰策略(Eviction Policy)
如果过期 Key 没有及时删除,导致 内存达到 maxmemory 限制,Redis 会采用 内存淘汰策略 释放空间,主要有三类:
(1) 直接拒绝写入
noeviction
(默认策略):- 机制:当 Redis 内存满了,拒绝新的写入请求,返回错误。
- 适用场景:适用于 不能丢失数据 的场景(如金融交易数据)。
- 缺点:可能导致系统不可用。
(2) 仅淘汰带过期时间(TTL)的 Key
volatile-lru
:淘汰 带 TTL 的 Key,按 LRU(最近最少使用)删除。volatile-lfu
:淘汰 带 TTL 的 Key,按 LFU(最少使用)删除。volatile-random
:随机删除 带 TTL 的 Key。volatile-ttl
:优先删除 TTL 最短的 Key。
(3) 淘汰所有 Key
allkeys-lru
:在 所有 Key 中,删除 最近最少使用(LRU) 的 Key。allkeys-lfu
:在 所有 Key 中,删除 最少使用(LFU) 的 Key。allkeys-random
:随机删除 任意 Key。
淘汰策略对比
策略 | 适用范围 | 适用场景 | 优点 | 缺点 |
---|---|---|---|---|
noeviction | 所有 Key | 不能丢失数据的业务 | 数据绝对安全 | 可能导致 Redis 无法写入 |
allkeys-lru | 所有 Key | 普通缓存(如 Web 缓存) | 保留热点数据 | LRU 计算有额外开销 |
volatile-lru | 仅带 TTL | 有过期时间的缓存 | 保留热点缓存数据 | TTL 过少时,可能无 Key 可删除 |
allkeys-random | 所有 Key | 低优先级缓存 | 简单高效 | 可能误删热点数据 |
volatile-random | 仅带 TTL | 无访问规律的缓存 | 低计算成本 | 命中率低 |
volatile-ttl | 仅带 TTL | 定期缓存数据 | 优先删除即将过期的数据 | TTL 设定不合理可能影响命中率 |
allkeys-lfu | 所有 Key | 热点数据变化快 | 优先保留高频访问数据 | 计算比 LRU 高 |
volatile-lfu | 仅带 TTL | 高频访问缓存 | 结合访问频率和 TTL 进行优化 | 计算比 LRU 高 |
5. 综述
- 为什么 Redis 需要设置过期时间?
- 释放内存,防止数据无限增长。
- 保证数据实时性,避免使用陈旧数据。
- 提高缓存命中率,让 Redis 保留热点数据。
- 符合业务需求(如验证码、Token 需要自动失效)。
- Redis 如何判断 Key 是否过期?
- 惰性删除:访问 Key 时检查,若过期则删除。
- 定期删除:每 100ms 随机检查部分 Key,并删除过期 Key。
- Redis 过期 Key 如何删除?
- 惰性删除 + 定期删除 + 内存淘汰策略 结合,平衡 性能 和 内存占用。
- Redis 如何在内存满时清理数据?
- 默认拒绝写入(
noeviction
) - 基于 LRU/LFU/TTL 的内存淘汰策略
- 随机淘汰或基于访问频率、TTL 进行优化
- 默认拒绝写入(
通过合理设置 过期时间 + 淘汰策略,可以让 Redis 高效管理内存,保证缓存数据的 可用性和实时性。