以下是一个 Node.js 监听 Redis key 变化的完整示例,包含详细的配置和实现步骤:
一、环境准备
- 启用 Redis 键空间通知
编辑 redis.conf
并添加:
notify-keyspace-events "KEA" # 启用所有键空间和键事件通知
重启 Redis 或使用命令临时启用:
redis-cli config set notify-keyspace-events "KEA"
安装依赖
npm install ioredis
二、Node.js 监听脚本
const Redis = require('ioredis'); // 配置 Redis 连接 const redis = new Redis({ host: 'localhost', // Redis 服务器地址 port: 6379, // Redis 服务器端口 password: 'your-password' // 如果有密码 }); // 创建专用的订阅客户端(建议与主客户端分离) const subscriber = new Redis({ host: 'localhost', port: 6379, password: 'your-password' }); // 订阅所有 key 变化事件 async function subscribeToKeyEvents() { try { // 订阅键空间事件(格式:__keyspace@<db>__:<key>) await subscriber.subscribe('__keyspace@0__:*'); // 订阅键事件事件(格式:__keyevent@<db>__:<event>) await subscriber.subscribe('__keyevent@0__:set'); await subscriber.subscribe('__keyevent@0__:del'); console.log('已成功订阅 Redis key 变化事件'); } catch (error) { console.error('订阅失败:', error); } } // 处理接收到的事件 subscriber.on('message', (channel, message) => { if (channel.startsWith('__keyspace@')) { // 键空间事件:message 是事件类型(如 set、del) const key = channel.split(':')[1]; console.log(`Key ${key} 发生变化: ${message}`); handleKeyChange(key, message); } else if (channel.startsWith('__keyevent@')) { // 键事件事件:message 是 key 名称 const event = channel.split(':')[1]; console.log(`事件 ${event} 发生在 Key: ${message}`); handleKeyEvent(message, event); } }); // 自定义处理函数 - 键变化 function handleKeyChange(key, event) { switch (event) { case 'set': // 处理 key 设置事件 redis.get(key).then(value => { console.log(`Key ${key} 的新值是: ${value}`); }); break; case 'del': // 处理 key 删除事件 console.log(`Key ${key} 已被删除`); break; case 'expire': // 处理 key 过期事件 console.log(`Key ${key} 已过期`); break; default: console.log(`Key ${key} 的其他事件: ${event}`); } } // 自定义处理函数 - 事件发生 function handleKeyEvent(key, event) { console.log(`事件 ${event} 影响了 Key: ${key}`); // 根据事件类型执行不同逻辑 } // 启动订阅 subscribeToKeyEvents(); // 优雅退出 process.on('SIGINT', () => { subscriber.quit(); redis.quit(); console.log('已断开 Redis 连接'); process.exit(); });
三、测试示例
运行脚本后,在 Redis 客户端执行以下命令测试:
# 设置 key redis-cli set user:1 "John Doe" # 删除 key redis-cli del user:1 # 设置带过期时间的 key redis-cli setex temp:key 60 "value"
Node.js 脚本将输出:
Key user:1 发生变化: set Key user:1 的新值是: John Doe 事件 set 发生在 Key: user:1 Key user:1 发生变化: del Key user:1 已被删除 事件 del 发生在 Key: user:1 Key temp:key 发生变化: set Key temp:key 的新值是: value 事件 set 发生在 Key: temp:key ...60秒后... Key temp:key 发生变化: expire Key temp:key 已过期 事件 expire 发生在 Key: temp:key
四、关键配置说明
- Redis 事件类型
KEA
:启用所有键空间和键事件(生产环境建议按需启用,如Ex
仅监听过期事件)- 常用事件:
set
、del
、expire
、rename
、hset
等
- 订阅模式
__keyspace@<db>__:<key>
:监听特定 key 的所有事件__keyspace@<db>__:*
:监听所有 key 的所有事件__keyevent@<db>__:<event>
:监听特定事件的所有 key
- 多数据库支持
- 将
0
替换为实际数据库编号(如__keyspace@1__:*
)
- 将
五、生产环境注意事项
- 性能影响
- 大量事件可能影响 Redis 性能,建议仅监听必要事件。
- 可靠性保障
- 使用
ioredis
的自动重连机制(默认开启) - 添加事件处理的重试和幂等性
- 使用
- 安全配置
- 使用 Redis 密码和 TLS 加密
- 通过
max_connections
限制连接数
- 监控与告警
- 监控 Redis 命令耗时和 CPU 使用率
- 设置事件处理超时告警