0%

redis过期提醒

Redis 过期提醒功能详解:基于键空间事件的实现

Redis 的 notify-keyspace-events 配置提供了键空间事件通知功能,可实时监听键的过期、删除、修改等事件,其中过期提醒是最常用的场景(如订单超时取消、会话过期清理等)。本文基于 Redis 6.0.10 版本,详解过期提醒的配置、订阅方式及实践注意事项。

核心原理:键空间事件(Keyspace Events)

Redis 的事件通知基于发布 - 订阅(Pub/Sub) 机制:当键发生特定操作(如过期、删除)时,Redis 会自动向指定频道发布事件消息,客户端通过订阅这些频道即可实时获取通知。

  • 事件分类:
    • keyspace 事件:以 __keyspace@<db>__:<key> 为频道,消息为事件类型(如 expired)。
    • keyevent 事件:以 __keyevent@<db>__:<event> 为频道,消息为键名(如 order:1001)。
      (过期提醒通常关注 keyevent 事件,直接获取过期的键名。)

配置开启过期提醒

配置 notify-keyspace-events

redis.conf 中设置事件通知类型,开启过期事件(x)和键事件(E):

1
notify-keyspace-events Ex
  • E:启用 keyevent 事件(按事件类型订阅)。
  • x:启用过期事件(键过期时触发)。

动态修改配置(无需重启)

通过 config set 命令临时开启(重启后失效,需同步到 redis.conf):

1
2
127.0.0.1:6379> config set notify-keyspace-events Ex
OK

订阅过期事件

订阅指定数据库的过期事件

通过 PSUBSCRIBE 订阅带通配符的频道(支持所有数据库或指定数据库):

示例 1:订阅所有数据库的过期事件
1
2
3
4
5
6
# 客户端 1:订阅频道 __keyevent@*__:expired(* 匹配所有数据库)
127.0.0.1:6379> PSUBSCRIBE __keyevent@*__:expired
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "__keyevent@*__:expired"
3) (integer) 1
示例 2:订阅数据库 0 的过期事件
1
2
3
4
5
127.0.0.1:6379> SUBSCRIBE __keyevent@0__:expired
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "__keyevent@0__:expired"
3) (integer) 1

触发过期事件

在另一个客户端设置过期键,验证通知是否生效:

1
2
3
# 客户端 2:设置键 order:1001 10秒后过期
127.0.0.1:6379> SET order:1001 "paid" EX 10
OK

10 秒后,客户端 1 会收到过期通知:

1
2
3
4
5
# 客户端 1 收到的消息
1) "pmessage"
2) "__keyevent@*__:expired"
3) "__keyevent@0__:expired"
4) "order:1001" # 过期的键名

实践注意事项

1. 事件触发的延迟性

  • 过期事件并非 “键过期瞬间” 立即触发,而是在键被实际删除时触发。
  • Redis 对过期键的删除采用 “惰性删除 + 定期删除” 策略,因此事件可能延迟(最长不超过hz配置的扫描周期,默认 10 次 / 秒)。
    • 若需严格时效性,建议结合业务逻辑主动检查(如定时任务)。

2. 订阅客户端的可靠性

  • 发布 - 订阅机制是无状态的:若订阅客户端断线,重连后会丢失断线期间的事件。
  • 解决方案:
    • 使用 Redis Stream 或消息队列(如 Kafka)存储事件,客户端从队列消费(需手动实现)。
    • 对关键业务,采用 “事件通知 + 定时补偿” 双重保障。

3. 性能影响

  • 开启事件通知会消耗额外 CPU 和内存(尤其是高频过期场景)。
  • 建议:
    • 仅开启必要的事件类型(如只开启 Ex 而非 A 所有事件)。
    • 避免对大量短期过期键(如 1 秒内)启用通知,减少事件风暴。

4. 键名解析

  • 事件消息仅包含键名,需在键名中嵌入业务标识(如 order:1001 中的订单 ID 1001),便于后续处理。

应用场景

  1. 订单超时取消
    • 订单创建时设置 order:<id> 键,过期时间为订单超时时间(如 30 分钟)。
    • 订阅过期事件,收到 order:<id> 时触发取消订单逻辑。
  2. 会话过期清理
    • 用户会话 session:<uid> 过期时,收到事件后清理关联资源(如临时文件)。
  3. 缓存过期更新
    • 缓存键 cache:<key> 过期时,自动触发从数据库加载最新数据到缓存。

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10