如何在(io)redis中执行密钥过期后的回调?

z6psavjg  于 2022-11-28  发布在  Redis
关注(0)|答案(1)|浏览(155)

对于我正在开发的一个应用程序,我计划不仅从缓存中读取数据,还将数据更新写入缓存中(对于更改非常频繁的数据)。然而,为了使其正常工作,我需要能够处理密钥/数据过期事件,以便在一段时间内不进行调整时将其保存到数据库中。
我尝试过使用redis.psubscribe()和redis.on('pmessage'),但是这些解决方案似乎没有任何作用(除了将其连接到与我设置/获取数据的客户端相同的客户端,这将返回一个错误)。
是否有最新的方法来处理(io)redis(nodejs)中的过期?

ru9i0ody

ru9i0ody1#

你可以使用keyspace事件来监听密钥过期事件,你需要两个不同的通道,一个用于发布事件(主通道),另一个用于监听过期事件,Redis的默认行为是只返回过期事件消息中过期元素的密钥,解决方法可以在here中找到,下面是使用该解决方法的简单实现:

import Redis from 'ioredis';

const subscribeChannel = new Redis({
   host: 'localhost',
   port: '6379',
   db: 0,
});

const publishChannel = new Redis({
   host: 'localhost',
   port: '6379',
   db: 0,
});

function set(channel, key, value, seconds){
   channel.set(key, value);

   // use shadowkey to access the value field on the expire event message
   channel.set(`${key}:${value}`, '');

   // set expire time on shadowkey
   channel.expire(`${key}:${value}`, seconds);
}

publishChannel.on('ready', () => {

   // configure keyspaces event and specify expiring events with "Ex"
   publishChannel.config("SET", "notify-keyspace-events", "Ex");

   // subscribe to the 
   subscribeChannel.subscribe("__keyevent@0__:expired");

   // listen for expiring event messages
   subscribeChannel.on('message', async(channel, message) => {

   // retrieve key and value from shadowkey
   const [key, value] = message.split(":");

   // store value in the main storage
   db.insert(value);

   // delete actual value from the redis store
   publishChannel.del(key);
 });

   // set "value" with "key" and set it to expire after 10 seconds
   set(publishChannel, "key", "value", 10);

});

相关问题