Redis Node.js Pub/Sub切换数据库后无法接收过期事件问题
问题原因及修复方案
核心问题
你订阅的是数据库0的过期事件频道__keyevent@0__:expired,但实际在数据库4中设置过期key,Redis会把过期事件发送到对应数据库的专属频道__keyevent@4__:expired,自然收不到消息。另外代码存在异步执行顺序问题,比如连接未完全建立就执行后续命令,可能引发潜在异常。
修复后的代码
const redis = require("redis"); async function init() { // 初始化发布客户端 const pub = redis.createClient({ url: process.env.REDIS_URL }); await pub.connect(); // 全局开启过期事件通知(确保命令执行完成) await pub.configSet("notify-keyspace-events", "Ex"); // 切换到数据库4并设置过期key await pub.select(4); await pub.setEx('mm', 5, "lopl"); // 初始化订阅客户端 const sub = pub.duplicate(); await sub.connect(); // 切换到数据库4,订阅对应数据库的过期事件频道 await sub.select(4); sub.subscribe("__keyevent@4__:expired", (key) => { console.log("key=> ", key); }); } init().catch(err => console.error(err));
关键修复点
- 订阅频道改为
__keyevent@4__:expired,与操作的数据库编号保持一致 - 使用
async/await严格控制命令执行顺序,避免异步竞态问题 - 每个客户端的数据库切换、命令执行都等待完成,保证状态正确
额外说明
- Redis键空间事件频道格式为
__keyevent@<dbnum>__:<event>,<dbnum>必须和目标数据库编号匹配 configSet是全局生效命令,只需执行一次,无需每个客户端重复设置- 订阅客户端切换数据库后,只会接收该数据库的事件,符合业务逻辑
内容的提问来源于stack exchange,提问作者meaow meaow
相关产品推荐
相关产品推荐

