Redis 数据删除策略

Redis 的删除策略分三大块:过期键删除策略内存淘汰策略(内存满了删谁)主动手动删除,平时做缓存开发这两块是高频踩坑点,我分开说清楚。

一、过期键删除策略:给 key 设置过期时间后,怎么删掉失效数据

我们业务里大量缓存都会加 expire 设置过期,Redis 有三种删除方式配合使用。

1. 惰性删除(被动删除,核心机制)

  • 逻辑:key 过期后不会立刻删,下次访问这个 key 的时候,Redis 先判断是否过期,过期直接删除再返回空。
  • 优点:几乎不消耗 CPU,只有读写时才做判断,平时无额外开销。
  • 缺点:如果一个过期 key 长期没人访问,会一直占内存,造成内存泄漏。比如冷门商品缓存过期后没人查,一直堆积。

2. 定期删除(主动抽样清理,弥补惰性删除缺陷)

Redis 每隔一段时间(默认 100ms)执行一次清理任务:

  1. 随机抽取一定数量带过期的 key;
  2. 删掉其中已经过期的;
  3. 如果本轮过期 key 占比超过阈值,继续多抽一轮,防止过期 key 堆积。
  • 优点:均衡 CPU 和内存,避免大量过期 key 占内存。
  • 缺点:只是抽样,不是遍历全库,依然会残留部分过期 key,没法彻底清干净。

3. 结合使用

Redis 默认是 惰性删除 + 定期删除 搭配。 但即便这样,高并发、海量 key 场景下,还是会有大量过期数据残留,内存持续上涨,这时候就需要内存淘汰策略兜底。

二、内存淘汰策略:maxmemory 达到上限时,系统自动删数据

业务机器内存有限,配置 maxmemory 限制 Redis 最大使用内存,内存打满后执行淘汰策略,共 6 种,分两大类:

第一类:不淘汰任何数据(线上缓存基本不用)

  1. noeviction(默认策略) 内存满后,所有新增、修改 key 的写命令直接报错,读命令正常执行。 适合 Redis 只存少量固定配置、不做大量缓存写入的场景;缓存业务绝对不能用,流量上来直接大量报错。

第二类:淘汰带过期时间的 key(优先删过期缓存,推荐业务使用)

  1. volatile-lru 只在设置了过期时间的 key 里,淘汰最近最少使用(LRU)的数据。
  2. volatile-lfu 只在过期 key 里,淘汰访问频次最低(LFU)的数据,新版本更推荐。
  3. volatile-random 过期 key 里随机删,基本不用,命中率不可控。
  4. volatile-ttl 过期 key 里优先删剩余存活时间最短的,适合有统一过期时效的临时缓存。

第三类:淘汰全部 key(包含没设过期的持久化数据)

  1. allkeys-lru / allkeys-lfu / allkeys-random 不区分是否设置过期,整个库内按规则删除。 如果 Redis 既存持久化业务数据又存缓存,不建议开,会把重要永久数据删掉。

线上缓存选型总结(面试加分)

  1. 绝大多数互联网缓存:allkeys-lfu(Redis4.0+) 按访问频次淘汰,热点数据永远留在内存,冷缓存优先清理,缓存命中率最高;
  2. 区分业务,一部分永久数据、一部分过期缓存:volatile-lfu,只动过期缓存,保护永久配置 key;
  3. 简单临时缓存,统一过期时间:volatile-ttl。

补充:Redis LRU/LFU 不是完整算法

为了性能,Redis 不是维护完整链表统计所有 key,而是随机抽样少量 key 对比,近似实现,性能损耗极低。

三、主动手动删除策略(业务代码主动清理)

除了自动删除,我们开发时会手动操作清理数据,分几种场景:

  1. DEL key:同步删除单个 / 多个 key,阻塞主线程,大数据量 hash/list 慎用;
  2. UNLINK key(异步删除,线上推荐) 把释放内存操作丢到后台子线程,主线程不阻塞,删除大集合无卡顿;
  3. 批量清理
  • flushdb:清空当前库所有 key;
  • flushall:清空所有数据库; 支持 flushdb async 异步清空,避免阻塞;
  1. 集合精细化删除:hdel、lpop、zrem 等,只删除集合内部分元素,不删除整个 key;
  2. 业务主动更新:更新数据库时同步删除对应缓存,避免缓存脏数据(Cache-Aside 常用方案)。

四、业务踩坑总结

  1. 只靠过期删除,不配置 maxmemory 淘汰:过期冷 key 堆积,内存溢出 OOM;
  2. 使用 noeviction:流量高峰新增缓存直接报错,接口大量 500;
  3. 大量使用 DEL 删除大 list/hash:主线程阻塞,Redis 卡顿;改用 UNLINK;
  4. 永久业务 key 和缓存混存,使用 allkeys 淘汰:核心配置被误删,业务故障;
  5. LRU 适合短期热点,LFU 适合长期稳定热点,现在新项目优先 LFU。

简短收尾总结

Redis 删除分为三层:

  1. 过期 key 靠「惰性删除 + 定期删除」自动清理过期数据;
  2. 内存打满触发 6 种内存淘汰策略,线上缓存优先 allkeys-lfu;
  3. 业务侧通过 DEL/UNLINK、批量清空命令主动手动删除; 生产环境必须配置 maxmemory + 合理淘汰策略,防止内存溢出,同时大对象删除优先异步 unlink 避免阻塞。
相关推荐
ClouGence1 小时前
SQL Server CDC 如何降低主库压力?Always On 备库读取实践
数据库·后端·sql·sqlserver
尽兴-2 小时前
Redis 为什么快?
数据库·redis·内存
林澈在路上2 小时前
最新版权清晰 AI音乐写歌工具软件App推荐 商用全场景实测指南
数据库·人工智能·ai·aigc·音频
Flittly2 小时前
【AgentScope Java新手村系列】(17)长期记忆系统
java·spring boot·spring
Full Stack Developme2 小时前
正则表达式的使用教程
java·数据库·正则表达式
大郭鹏宇3 小时前
MongoDB快速实战与基本原理入门
数据库·mongodb
KASH_SHADOW3 小时前
8-Mysql的安装与配置
数据库·mysql·adb
澈2073 小时前
【无标题】QT入门第十二天:数据库编程(下)模型视图与数据展示 | 零基础学QT
数据库·qt·oracle