redis 什么情况会自动删除key

在 Redis 中,key 的自动删除 主要由两种核心机制触发:过期删除(针对设置了 TTL 的 key) ​ 和 内存淘汰(针对内存超限时的 key) 。以下是具体场景、策略及原理的详细说明:

一、过期删除:Key 达到预设生存时间(TTL)后自动删除

Redis 支持为 key 设置过期时间(Time To Live, TTL) ,当 key 的存活时间超过 TTL 时,会被自动删除。这是最常见的"自动删除"场景。

1. 如何设置过期时间?

通过以下命令为 key 设置过期时间(单位:秒/毫秒):

  • EXPIRE key seconds:设置 key 在 seconds秒后过期(如 EXPIRE user:100 3600表示 1 小时后过期)。
  • PEXPIRE key milliseconds:设置 key 在 milliseconds毫秒后过期(如 PEXPIRE session:abc 1800000表示 30 分钟后过期)。
  • SET key value EX seconds:创建 key 时直接指定过期时间(如 SET name "Alice" EX 60表示 60 秒后过期)。
  • EXPIREAT key timestamp:设置 key 在某个 Unix 时间戳(秒)过期(如 EXPIREAT order:2024 1717171200表示 2024-06-01 00:00:00 过期)。

2. 过期删除的触发策略(核心!)

Redis 并非实时扫描并删除所有过期 key(避免 CPU 资源浪费),而是通过 "惰性删除 + 定期删除" ​ 结合的混合策略:

① 惰性删除(Lazy Expiration)
  • 触发时机 :当客户端访问某个 key​ 时,Redis 会先检查该 key 是否已过期。

  • 处理逻辑

    • 若 key 已过期:立即删除该 key,并返回 nil(表示 key 不存在);
    • 若 key 未过期:正常返回值。
  • 优点:对 CPU 友好(仅在访问时检查),不影响其他操作;

  • 缺点:若过期 key 长期不被访问,会一直占用内存("内存泄漏"风险)。

② 定期删除(Periodic Expiration)
  • 触发时机 :Redis 每隔一段时间(默认 100ms ,可通过 hz配置调整,范围 1-500),主动随机抽取部分设置了过期时间的 key 进行检查。

  • 处理逻辑

    • 从设置了过期时间的 key 中随机选取 20 个 (默认值,可通过 active-expire-effort调整)进行检查;
    • 删除其中已过期的 key;
    • 若本轮检查中,超过 25% 的 key 已过期(说明过期 key 较多),则重复上述步骤(最多循环 10 次,避免阻塞主线程)。
  • 优点:主动释放部分过期 key 内存,弥补惰性删除的不足;

  • 缺点:删除频率和影响范围可控(避免 CPU 占用过高)。

3. 过期删除的注意事项

  • 过期精度:Redis 的过期时间是"近似精确"的(误差通常在毫秒级),受定期删除的频率影响,极端情况下可能延迟几秒删除。
  • 永不过期的 key :若未设置 TTL(或 TTL 为 -1),key 不会自动删除(除非被内存淘汰)。
  • 取消过期时间 :通过 PERSIST key命令可移除 key 的过期时间,使其永久有效。

二、内存淘汰:内存使用达到上限时自动删除 Key

当 Redis 的内存使用量达到 maxmemory配置的上限时(默认无限制,需手动配置),会触发 内存淘汰机制,根据预设策略自动删除部分 key 以释放内存。

**1. 核心配置:maxmemorymaxmemory-policy**​

  • maxmemory <bytes> :设置 Redis 最大可用内存(如 maxmemory 4gb表示最大使用 4GB 内存)。
  • maxmemory-policy <policy> :设置内存淘汰策略(决定删除哪些 key),默认策略为 noeviction(不淘汰,直接返回错误)。

2. 内存淘汰策略(7 种可选)

根据 key 是否设置过期时间,分为两类策略:

① 针对"已设置过期时间的 key"的策略
  • volatile-lru (默认推荐):从已设置过期时间的 key 中,删除最近最少使用(LRU) 的 key。
  • volatile-lfu :从已设置过期时间的 key 中,删除最近最不频繁使用(LFU) 的 key(Redis 4.0+ 支持)。
  • volatile-ttl :从已设置过期时间的 key 中,删除剩余 TTL 最短 的 key(即将过期的优先删)。
  • volatile-random :从已设置过期时间的 key 中,随机删除 一个 key。
② 针对"所有 key"的策略
  • allkeys-lru :从所有 key 中,删除最近最少使用(LRU)的 key(适合缓存场景,保留热点数据)。
  • allkeys-lfu:从所有 key 中,删除最近最不频繁使用(LFU)的 key(Redis 4.0+ 支持)。
  • allkeys-random:从所有 key 中,随机删除一个 key。
③ 不淘汰策略
  • noeviction :内存超限时,不删除 key,直接返回 OOM command not allowed when used memory > 'maxmemory'错误(默认策略,需谨慎使用)。

3. 内存淘汰的触发流程

  1. 当 Redis 执行写操作(如 SETLPUSH)时,检查内存使用是否超过 maxmemory
  2. 若超过,根据 maxmemory-policy选择待删除的 key;
  3. 删除 key 后,若内存仍超限,重复步骤 2(直到内存足够或触发 noeviction错误)。

4. 内存淘汰的注意事项

  • LRU/LFU 近似算法 :Redis 并未实现严格的 LRU/LFU(避免遍历所有 key 耗时),而是通过随机采样 (默认 5 个 key,可通过 maxmemory-samples调整)估算最近使用情况,平衡精度与性能。
  • 持久化影响:内存淘汰仅删除内存中的 key,若 key 已持久化到 RDB/AOF 文件,重启后仍会加载(需结合持久化策略)。

三、其他自动删除场景(罕见)

**1. 主动触发 FLUSHDB/FLUSHALL**​

  • FLUSHDB:删除当前数据库的所有 key(需谨慎,不可逆);
  • FLUSHALL:删除所有数据库的 key。 这两个命令是手动触发的"批量删除",不属于"自动删除",但可能被误配置为定时任务(如 cron 脚本)导致 key 被自动清除。

2. 集群模式下 Slot 迁移

在 Redis Cluster 中,当槽位(Slot)从一个节点迁移到另一个节点时,源节点会自动删除已迁移的 key(目标节点会新增 key)。这属于集群内部的自动数据同步,非用户感知的"删除"。

总结:Redis 自动删除 Key 的核心场景

触发类型 核心条件 策略/机制 典型场景
过期删除 Key 的 TTL 到期 惰性删除(访问时检查)+ 定期删除(随机抽查) 验证码(5 分钟过期)、会话 Token(30 分钟过期)
内存淘汰 内存使用达到 maxmemory上限 maxmemory-policy删除(LRU/LFU/TTL/随机) 缓存服务器内存不足时,删除冷数据释放空间

配置建议

  • 过期删除:根据业务需求合理设置 TTL(如缓存数据设短期 TTL,永久数据不设 TTL);
  • 内存淘汰 :缓存场景推荐 allkeys-lru(保留热点数据),持久化数据场景推荐 volatile-lru(仅删除临时数据);
  • 监控 :通过 INFO stats命令查看 expired_keys(过期删除的 key 总数)和 evicted_keys(内存淘汰的 key 总数),评估自动删除效果。

通过这两种机制,Redis 实现了"自动管理 key 生命周期"的能力,既保证了内存效率,又避免了手动维护的繁琐。

相关推荐
ShaneD7711 小时前
BaseContext:如何在Service层“隔空取物”获取当前登录用户ID?
后端
ShaneD7712 小时前
解决idea错误提示:无法解析'表名'
后端
李拾叁的摸鱼日常2 小时前
从 Java 8 升级视角看Java 17 新特性详解
java·后端
淡定__0092 小时前
深入理解 .NET 中的依赖注入(DI):从原理到实战
后端
Ankkaya2 小时前
小白服务器踩坑(2)- 自动化部署
后端
回家路上绕了弯2 小时前
Vavr 工具实用指南:Java 函数式编程的高效落地方案
分布式·后端
开心就好20252 小时前
没有 Mac 怎么上架 iOS 应用 跨平台团队的可行交付方案分析
后端
aiopencode2 小时前
构建可靠的 iOS 日志导出体系,从真机日志到系统行为的多工具协同实践
后端
期待のcode2 小时前
MyBatis-Plus通用Service
java·后端·mybatis·springboot