如何使用节点接收 Redis 过期事件?
How to receive Redis expire events with node?
我想听Redis 的expire 事件。
我已经在 redis.conf
上配置了 notify-keyspace-events "AKE"
,这是我在节点上的代码:
const redis = require('redis');
const client = redis.createClient();
const subscriber = redis.createClient();
const KEY_EXPIRING_TIME = 10; // seconds
client.setex('myKey', KEY_EXPIRING_TIME, 'myValue');
subscriber.on('message', function(channel, msg) {
console.log( `On ${channel} received ${msg} event`);
});
subscriber.subscribe('myKey', function (err) {
console.log('subscribed!');
});
我希望在 10 秒内看到事件被触发。
setex 命令正常工作,10 秒后密钥不在数据库中,我在尝试捕获事件时遇到问题。
我做错了什么?
方法一:-
必须使用setInterval函数来定期检查值是否过期。我知道这不等于监听事件。但是,它间接地达到了目的。
下面的代码每 5 秒检查一次值。
const redis = require('redis');
const client = redis.createClient();
const subscriber = redis.createClient();
const KEY_EXPIRING_TIME = 10; // seconds
var args = ['myKey', KEY_EXPIRING_TIME, 'myValue'];
client.setex('myKey', KEY_EXPIRING_TIME, 'myValue');
subscriber.on('message', function(channel, msg) {
console.log( `On ${channel} received ${msg} event`);
});
subscriber.subscribe('myKey', function (err) {
console.log('subscribed!');
});
setInterval(function() {
client.get('myKey', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 5e3);
方法二:-
redis-notifier
可以用来监听事件。但是,它需要 Python >= v2.5.0 & < 3.0.0 才能安装此软件包。
var RedisNotifier = require('redis-notifier');
var eventNotifier = new RedisNotifier(redis, {
redis : { host : '127.0.0.1', port : 6379 },
expired : true,
evicted : true,
logLevel : 'DEBUG' //Defaults To INFO
});
//Listen for event emission
eventNotifier.on('message', function(pattern, channelPattern, emittedKey) {
var channel = this.parseMessageChannel(channelPattern);
switch(channel.key) {
case 'expired':
this._handleExpired(emittedKey);
break;
case "evicted":
this._handleEvicted(emittedKey);
break;
default:
logger.debug("Unrecognized Channel Type:" + channel.type);
}
});
实际上可以使用订阅客户端到特定频道 ('__keyevent@db__:expired'
) 来收听 "expired" 类型 keyevent notification 并收听其 消息 事件。
不需要 setInterval / setTimeout 或其他库
概念验证(工作:使用 NodeJS v.9.4.0 测试)
const redis = require('redis')
const CONF = {db:3}
var pub, sub
//.: Activate "notify-keyspace-events" for expired type events
pub = redis.createClient(CONF)
pub.send_command('config', ['set','notify-keyspace-events','Ex'], SubscribeExpired)
//.: Subscribe to the "notify-keyspace-events" channel used for expired type events
function SubscribeExpired(e,r){
sub = redis.createClient(CONF)
const expired_subKey = '__keyevent@'+CONF.db+'__:expired'
sub.subscribe(expired_subKey,function(){
console.log(' [i] Subscribed to "'+expired_subKey+'" event channel : '+r)
sub.on('message',function (chan,msg){console.log('[expired]',msg)})
TestKey()
})
}
//.: For example (create a key & set to expire in 10 seconds)
function TestKey(){
pub.set('testing','redis notify-keyspace-events : expired')
pub.expire('testing',10)
}
不需要 setInterval / setTimeout 或其他库
您可以从代码下方获取每个过期密钥。
import { createClient } from "redis";
const pub=createClient({ url: process.env.REDIS_URL });
pub.connect();
pub.configSet("notify-keyspace-events", "Ex");
const sub=pub.duplicate();
sub.connect();
sub.subscribe("__keyevent@0__:expired", (key) => {
console.log("key=> ", key)
})
注:此代码已通过redis@4.0.0
测试
我想听Redis 的expire 事件。
我已经在 redis.conf
上配置了 notify-keyspace-events "AKE"
,这是我在节点上的代码:
const redis = require('redis');
const client = redis.createClient();
const subscriber = redis.createClient();
const KEY_EXPIRING_TIME = 10; // seconds
client.setex('myKey', KEY_EXPIRING_TIME, 'myValue');
subscriber.on('message', function(channel, msg) {
console.log( `On ${channel} received ${msg} event`);
});
subscriber.subscribe('myKey', function (err) {
console.log('subscribed!');
});
我希望在 10 秒内看到事件被触发。 setex 命令正常工作,10 秒后密钥不在数据库中,我在尝试捕获事件时遇到问题。
我做错了什么?
方法一:-
必须使用setInterval函数来定期检查值是否过期。我知道这不等于监听事件。但是,它间接地达到了目的。
下面的代码每 5 秒检查一次值。
const redis = require('redis');
const client = redis.createClient();
const subscriber = redis.createClient();
const KEY_EXPIRING_TIME = 10; // seconds
var args = ['myKey', KEY_EXPIRING_TIME, 'myValue'];
client.setex('myKey', KEY_EXPIRING_TIME, 'myValue');
subscriber.on('message', function(channel, msg) {
console.log( `On ${channel} received ${msg} event`);
});
subscriber.subscribe('myKey', function (err) {
console.log('subscribed!');
});
setInterval(function() {
client.get('myKey', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 5e3);
方法二:-
redis-notifier
可以用来监听事件。但是,它需要 Python >= v2.5.0 & < 3.0.0 才能安装此软件包。
var RedisNotifier = require('redis-notifier');
var eventNotifier = new RedisNotifier(redis, {
redis : { host : '127.0.0.1', port : 6379 },
expired : true,
evicted : true,
logLevel : 'DEBUG' //Defaults To INFO
});
//Listen for event emission
eventNotifier.on('message', function(pattern, channelPattern, emittedKey) {
var channel = this.parseMessageChannel(channelPattern);
switch(channel.key) {
case 'expired':
this._handleExpired(emittedKey);
break;
case "evicted":
this._handleEvicted(emittedKey);
break;
default:
logger.debug("Unrecognized Channel Type:" + channel.type);
}
});
实际上可以使用订阅客户端到特定频道 ('__keyevent@db__:expired'
) 来收听 "expired" 类型 keyevent notification 并收听其 消息 事件。
不需要 setInterval / setTimeout 或其他库
概念验证(工作:使用 NodeJS v.9.4.0 测试)
const redis = require('redis')
const CONF = {db:3}
var pub, sub
//.: Activate "notify-keyspace-events" for expired type events
pub = redis.createClient(CONF)
pub.send_command('config', ['set','notify-keyspace-events','Ex'], SubscribeExpired)
//.: Subscribe to the "notify-keyspace-events" channel used for expired type events
function SubscribeExpired(e,r){
sub = redis.createClient(CONF)
const expired_subKey = '__keyevent@'+CONF.db+'__:expired'
sub.subscribe(expired_subKey,function(){
console.log(' [i] Subscribed to "'+expired_subKey+'" event channel : '+r)
sub.on('message',function (chan,msg){console.log('[expired]',msg)})
TestKey()
})
}
//.: For example (create a key & set to expire in 10 seconds)
function TestKey(){
pub.set('testing','redis notify-keyspace-events : expired')
pub.expire('testing',10)
}
不需要 setInterval / setTimeout 或其他库
您可以从代码下方获取每个过期密钥。
import { createClient } from "redis";
const pub=createClient({ url: process.env.REDIS_URL });
pub.connect();
pub.configSet("notify-keyspace-events", "Ex");
const sub=pub.duplicate();
sub.connect();
sub.subscribe("__keyevent@0__:expired", (key) => {
console.log("key=> ", key)
})
注:此代码已通过redis@4.0.0
测试