Redis主节点单点决策过期键删除,通过expireIfNeeded函数在读写前检查并触发dbDelete及DEL广播;从节点不自主判断或扫描过期键,仅执行主节点同步的DEL命令,断连时可能长期保留逻辑过期key,重连后通过RDB或AOF重写清理,以此保障CP一致性。

主节点负责判断和触发过期KEY删除
Redis主从架构中,expireIfNeeded 函数只在主节点执行。每次读写命令(如 GET、SET)前,主节点会调用该函数检查目标 key 是否已过期;若过期,立即调用 dbDelete 删除,并向所有从节点广播一条 DEL 命令。
从节点不自行判断过期,也不主动扫描 expires 字典。它只忠实地执行来自主节点的写命令——包括这条显式的 DEL 操作。
- 主节点的惰性删除 + 定期删除仍照常运行,是过期清理的唯一决策源
- 从节点收到
DEL命令后才真正释放内存,此前即使key已逻辑过期,仍保留在从库内存中 - 如果主节点因高负载未及时触发惰性或定期删除,从节点上的过期
key会持续存在,直到收到对应DEL
网络中断时从节点可能长期保留过期KEY
当从节点与主节点断连(如网络分区),主节点上已过期并被删除的 key,不会同步到从节点。此时从节点的 key 状态与主节点严重不一致:它仍显示存在、可读取,且 TTL 返回值可能为负数或异常大。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 断连期间,从节点对过期
key的任何读请求都会返回旧值(因为没收到DEL) - 重连后,主节点通过全量同步(RDB)或部分同步(PSYNC2)补发缺失命令,但 RDB 文件本身已过滤过期
key,所以重连后从节点会清空这些键 - 若使用 AOF 持久化且开启
aof-rewrite,重写过程也会跳过已过期key,进一步保证从节点最终一致性
为什么不能让从节点自己删?
允许从节点独立执行过期检查会破坏主从数据一致性。例如:
- 主节点刚写入一个
key并设 TTL=1s,同时从节点本地时钟快了 2s → 从节点立刻判定过期并删除,而主节点尚未删除 - 主节点因定期删除未覆盖到该
key,而从节点随机扫描恰好命中并删掉 → 主从 key 集合出现差异 - 不同从节点的
hz配置或负载不同,导致过期行为时间点不统一,无法保证“同一时刻所有副本状态一致”
因此 Redis 强制由主节点单点决策,再通过命令传播实现强顺序一致性——这是 CAP 中优先保障 CP 的设计选择。
实际运维中容易忽略的关键点
监控和告警往往只看主节点内存与 expired_keys 指标,但真正影响业务的是从节点的“虚假存活”过期 key。比如缓存击穿场景下,客户端直连从节点读取到一个本该过期的旧商品价格,问题难以复现且日志无误。
-
INFO replication中的master_repl_offset和从节点的slave_repl_offset差值持续增大,是断连或复制延迟的直接信号 - 从节点的
INFO keyspace显示某 db 的keys数明显高于主节点,且expires字典大小相近,大概率存在积压的过期key - 不要依赖
TTL命令在从节点的返回值做业务判断——它可能返回正数(未过期)、-2(key 不存在)或 -1(key 存在但无 TTL),但绝不会准确反映“是否已被主节点逻辑过期”

















