
Redis集群里过期键不是“一到时间就立刻删”
Redis集群本身不主动扫描或批量清理过期键,它用的是“惰性删除 + 定期抽样删除”混合机制。这意味着:EXPIRE 设置的过期时间只是标记,真实删除依赖访问触发(惰性)或后台周期性随机抽查(定期)。集群模式下,每个分片(shard)独立执行这套逻辑,没有跨节点协调删除行为。
所以你看到内存没随过期时间下降,不是配置错了,而是机制使然。真正影响“删得快不快”的,是 hz 参数和实际访问模式:
hz 默认是 10,表示每秒执行 10 次定时抽样;在高吞吐、大量过期键场景下可调到 100(hz 100),但会略微增加 CPU 占用如果某个 key 长期不被访问,又没被抽样命中,它就会一直占着内存,直到下次抽样或被访问时才清理集群中某节点内存飙升,优先查 INFO memory 里的 expired_keys 和 evicted_keys,而不是默认认为“过期了就该没了”
LRU/LFU 淘汰策略只在内存满时才生效,且不替代过期机制
很多人误以为开了 allkeys-lru 就能“自动腾出过期键的空间”,其实不是:淘汰策略(maxmemory-policy)只在 used_memory > maxmemory 时触发,用于决定“删谁来腾地方”,而过期键是否已物理删除,取决于前面说的惰性+定期机制。
选 LRU 还是 LFU,关键看访问模式:
allkeys-lru:适合热点集中、新数据更可能被再访问的场景(比如最近商品列表)allkeys-lfu:适合有稳定长尾访问、某些冷 key 偶尔但持续被查的场景(比如用户档案缓存)注意:volatile-lru 等带 volatile- 前缀的策略,只对设置了 EXPIRE 的 key 生效;如果大量 key 没设过期时间,这些策略可能完全不触发淘汰LFU 需要 Redis 4.0+,且内部计数器有衰减逻辑,不是简单频次累加;频繁写入但极少读的 key,LFU 权重可能比你预想的低
集群环境下 maxmemory 必须按节点单独配,不能只看总量
Redis Cluster 是去中心化架构,每个 master 节点独立管理自己的内存和淘汰策略。假设你有 6 个 master 节点,总内存预算 12GB,不能只在配置里写 maxmemory 12gb —— 必须在每个节点的 redis.conf 里明确设为 maxmemory 2gb(或其他均分值)。
否则会出现:
部分节点提前触发 evicted_keys 上涨,请求开始报 (error) OOM command not allowed when used memory > ‘maxmemory’其他节点内存空闲,但无法自动借调,集群整体利用率失衡使用 redis-cli -c 连集群时,CONFIG GET maxmemory 返回的是当前连接节点的值,不是全局值,容易误判
验证过期与淘汰是否正常工作的三个命令
别只盯着业务响应慢,先用这几个命令快速定位瓶颈环节:
查当前节点过期键清理情况:INFO stats | grep expired_keys —— 如果长期不增长,说明抽样没覆盖到,或 hz 太低查是否有淘汰发生:INFO memory | grep evicted_keys —— 若为 0 但 mem_fragmentation_ratio > 1.5,可能是内存碎片而非淘汰问题手动模拟淘汰压力:redis-cli -h nodeA -p 6379 CONFIG SET maxmemory 1mb,然后 SET testkey "x" EX 300 多次,观察 evicted_keys 是否递增
集群中各节点状态不一致很常见,逐个连上去查比看汇总监控更可靠。过期逻辑和淘汰策略是两层独立机制,混在一起调,往往越调越乱。

评论(0)