订阅 Redis 过期事件在 c# 驱动程序中

本文关键字:驱动程序 事件 Redis 过期 订阅 | 更新日期: 2023-09-27 18:36:46

如果您将过期添加到要添加到 Redis 中的实体,例如在 ServiceStack.Redis 中:

redisClient.Set(elementKey, "some cached value", DateTime.Now.AddMinutes(2));

然后如何订阅元素的过期。期望的结果将是:

redisClient.Subscribe(elementKey, "expire", DoSomethingBasedOnKey)

订阅 Redis 过期事件在 c# 驱动程序中

实际上,

您可以订阅过期密钥事件,但就像 Matias 所说的那样,Redis 可能需要一些时间才能发布该事件。

Redis 有密钥空间通知,你可以在这里阅读它,

密钥空间通知允许客户端订阅发布/订阅通道,以便以某种方式接收影响 Redis 数据集的事件。

事件类型

实现密钥空间通知,为影响 Redis 数据空间的每个操作发送两种不同类型的事件。例如,针对数据库 0 中名为 mykey 的键的 DEL 操作将触发两条消息的传递,完全等效于以下两个 PUBLISH 命令:

发布keyspace@0:mykey del
发布keyevent@0:d el mykey

所以你需要的是订阅将在keyevent的过期命令上发布消息的频道(当达到ttl时也起作用),它的前缀将是这样的:"keyevent@0:已过期"

在我的情况下,计时准确性并不重要,所以我使用 ServiceStack C# Redis 客户端实现了它:

string EXPIRED_KEYS_CHANNEL = "__keyevent@0__:expired";    
using (IRedisClient client = redisClient.GetClient())
{
    using (var cacheSubscription = client.CreateSubscription())
    {
        cacheSubscription.OnMessage += (ch, expiredKey) =>
        {                            
            FireOnKeyExpired(expiredKey);
        };
        cacheSubscription.SubscribeToChannels(EXPIRED_KEYS_CHANNEL);
    }
}

更新:

确保配置 redis.conf 以允许过期密钥上的密钥事件:

通知密钥空间事件 Ex

或者像这样动态(重新启动实例时配置可能会丢失)

config set notify-keyspace-events Ex

也许您不知道当密钥过期时,过期消息不会完全发布:

过期事件的计时

与生存时间关联的键是 由 Redis 以两种方式过期:

  • 当命令访问密钥并发现密钥已过期时。
  • 通过后台系统,逐步在后台查找过期的密钥,以便能够 收集从未访问过的密钥。

我建议您最好的选择是使用一些任务计划程序(如内置的 Windows 任务计划程序或 Quartz.NET)来计划任务,以便在密钥必须过期时将消息发布到某个自定义 Redis PubSub 通道。