redis过期通知需同时满足服务端启用notify-keyspace-events ex和客户端精准订阅__keyevent@n__:expired频道;事件在键被实际删除时触发,非ttl归零即发,且无重试、不保证实时与可靠。

Redis 不会自动推送过期通知,必须同时满足两个硬性条件:服务端显式开启 notify-keyspace-events Ex,客户端精准订阅 __keyevent@0__:expired 频道。缺一不可,且配置错误或频道名偏差都会静默失败。
必须在 redis.conf 中启用 notify-keyspace-events Ex
Redis 默认完全禁用键空间事件,SET key val EX 60 执行成功不代表会发通知。关键点:
-
notify-keyspace-events必须设为Ex(E 大写,x 小写),不能是ex、"Ex"或AKE;引号会导致 Redis 静默忽略 - 该配置对所有数据库生效,无法按 db 单独开关
- 用
CONFIG SET notify-keyspace-events Ex可临时生效,但重启即丢——生产环境务必写入redis.conf并重启 Redis - 云托管 Redis(如阿里云、腾讯云)可能禁用
CONFIG SET,只能通过控制台修改或提交工单
订阅频道名必须严格匹配 __keyevent@N__:expired
不是 __keyevent@*:expired,也不是 __keyspace@0__:expired,更不是 expired——少一个下划线、错一位数字、大小写混用,都收不到消息。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
-
N是数据库编号,例如你用SELECT 2写入的 key,过期事件只发到__keyevent@2__:expired,订阅 @0 无效 - 用
redis-cli SUBSCRIBE '__keyevent@0__:expired'测试时,单引号必不可少,否则 shell 会把@当作特殊字符解析 - Redis Pub/Sub 无重试、无持久化:客户端断连期间的事件直接丢失,不能依赖它做强一致性业务
过期通知不是实时触发,而是“删除时通知”
__keyevent@0__:expired 消息不是在 TTL 归零那一刻发出的,而是在 Redis 主动清理该 key 的瞬间广播——这取决于删除策略:
- 惰性删除:只在访问 key 时检查过期,不访问就不发通知
- 定期删除:后台线程周期性扫描,有延迟(毫秒级到秒级不等)
- 内存压力大时,延迟可能更长;若 key 一直未被访问且未被定期扫描到,通知就永远不会来
- 事件只携带 key 名,不带 value、TTL、时间戳等任何上下文,无法判断是否重复或是否已处理
真正难搞的不是配置步骤,而是接受它的本质:这不是一个可靠的消息队列,而是一个尽力而为的异步信号。如果业务要求精确时效(比如支付订单 30 分钟关单),必须搭配定时任务兜底扫描 + 状态校验,不能只靠这个事件。










