redis某个key过期了,删除策略有哪些?

1 个回答

  • 夜太
    明知不可为而为之就是我最大的诚意
    Redis对**已过期的 key**有两类机制:**过期删除**(专门针对 TTL 到期)和**内存淘汰**(触发于内存压力,不一定是过期键)。 # 一、过期删除(TTL 到了以后怎么清) 1. **惰性删除(lazy / passive)** * 当客户端**访问**到某个 key 时,Redis 先检查它的过期时间;如果已过期,**当场删除**(对外表现为 key 不存在),然后再返回结果。 * 优点:不做无谓工作;缺点:从不过期访问的“冷键”可能**暂时占着内存**。 2. **定期删除(active expire cycle)** * 由服务器定时任务在后台**抽样扫描**各 DB 的过期字典,批量清理已过期的 key。 * 扫描强度受配置影响(如 `hz`、`active-expire-effort`),避免一次性扫太多而阻塞主线程。 * 这能清理那些“没人访问”的过期冷键,降低内存长期被占用的概率。 > 这两种机制并存:**访问时立即删 + 后台抽样扫**。所以过期后即使还没被定期任务扫到,**读出来也不会返回旧值**——会先删后报不存在。 3. **删除的释放方式:同步/异步** * `DEL` 为同步释放内存; * `UNLINK`/“lazy free” 为**异步释放**(交给后台线程),减少大键删除对主线程的阻塞。 * 可用配置开启过期删除走异步:`lazyfree-lazy-expire yes`(推荐在大 Value 场景)。 # 二、内存淘汰(内存打满才触发,不限于过期键) 设置了 `maxmemory` 且内存不足时,Redis会按 `maxmemory-policy` 淘汰键以继续服务。常见策略: * **noeviction**:不淘汰,直接报错(写命令失败) * **volatile-lru / allkeys-lru**:按 LRU 淘汰(只在有 TTL 的键里 / 在所有键里) * **volatile-lfu / allkeys-lfu**:按访问频率淘汰 * **volatile-random / allkeys-random**:随机淘汰 * **volatile-ttl**:优先淘汰**离过期最近**的键 > “volatile-*”只在**设置了过期时间**的键里挑;“allkeys-*”在全体键里挑。 > 淘汰时同样可配合 `lazyfree-lazy-eviction yes` 做**异步释放**内存。 # 三、开发运维要点 * **大量大键**:开启 `lazyfree-lazy-expire yes`,用 `UNLINK` 替代 `DEL`;避免一次性删除超大集合阻塞。 * **过期清理更积极**:调高 `active-expire-effort` 或 `hz`(慎重,过高会增加 CPU)。 * **监控**:关注 `expired_keys`、`evicted_keys`、内存水位与大键情况(`redis-cli --bigkeys`)。 * **业务语义**:强依赖“到点马上不可见”,Redis已满足(访问即删);强依赖“到点马上释放内存”,要配合定期删除参数/异步释放。 **一句话总结**: Redis 过期清理=**惰性删除 + 定期抽样**;内存吃紧时再按**淘汰策略**回收空间。为减少卡顿,可用 **UNLINK / lazyfree** 把释放动作放后台。
    发布于 2025-08-19 12:13 •IP属地 西藏
    举报
    评论
    收藏