你听说过Redis Keyspace Notifications吗?可能你们中的大多数人已经熟悉 Redis 甚至每天都在使用它,但是你知道如果发生密钥更改/过期我们可以得到“通知”吗?
什么键空间通知?
长话短说,它是一种 pub/sub 机制,可以让你监听 redis 中的数据变化。使用此功能可能有益的简单用例,例如喜欢,您希望在某些密钥过期时收到通知,您想要监视特殊密钥的更改,以及您能想到的任何其他扩展用例。如果您想仔细查看有关此的更多详细信息,可以访问此链接:https://redis.io/topics/notifications。
在Redis 中开启 Redis 键空间通知,默认情况下,Redis 键空间通知功能处于关闭状态。这意味着在任何密钥更改时都不会向订阅的客户端发送通知。
注意:
Redis 通知以遗忘的方式工作。这意味着如果客户端在发布通知后由于某种原因断开连接,它将不会在重新连接时收到通知。简而言之,通知不会持久化或排队。因此,直接使用它们并不是最可靠的,如果您的特定情况需要,您应该考虑一些变通方法以实现更可靠的交付。
要在Redis 中打开键命名空间通知,您需要修改 redis.config 文件或通过 redis-cli 使用CONFIG SET命令。根据您要为其创建通知的关键事件,命令参数如下:
K Keyspace events, published with __keyspace@<db>__ prefix.
E Keyevent events, published with __keyevent@<db>__ prefix.
g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
$ String commands
l List commands
s Set commands
h Hash commands
z Sorted set commands
x Expired events (events generated every time a key expires)
e Evicted events (events generated when a key is evicted for maxmemory)
A Alias for g$lshzxe, so that the "AKE" string means all the events.
CONFIG SET notify-keyspace-events KEx
命令执行后,当Redis 数据库中的密钥过期时,Redis 将开始向所有订阅的客户端发送通知。
也可以直接修改redis配置文件(redis.windows-service.conf和redis.windows.conf),如图:
![](https://img-blog.csdnimg.cn/img_convert/b37a66527250cf35ab060511fc5b7886.png)
![](https://img-blog.csdnimg.cn/img_convert/529a5937db7dad563e91e3f3555c6be4.png)
修改保存完成后,重启redis服务即可。
现在,在我们编写任何代码之前,我们需要引用StackExchange.Redis.NET Core 项目中的 NuGet 包,本人测试引用的是ColinChang.RedisHelper包。
StackExchange.Redis 示例:
我们现在准备好编写实际的通知订阅代码,一旦密钥过期从Redis 实例推送通知,该代码将注册一个要调用的委托,代码如下:
using StackExchange.Redis;
using System;
namespace RedisTestsConsoleApp
{
class Program
{
static void Main(string[] args)
{
string EXPIRED_KEYS_CHANNEL = "__keyevent@0__:expired";
String host = "127.0.0.1";
ConnectionMultiplexer connection = ConnectionMultiplexer.Connect(host);
ISubscriber subscriber = connection.GetSubscriber();
subscriber.Subscribe(EXPIRED_KEYS_CHANNEL, (channel, key) =>
{
Console.WriteLine($"EXPIRED: {key}");
}
);
Console.WriteLine("Listening for events...");
Console.ReadKey();
}
}
}
请注意,常量EXPIRED_KEYS_CHANNEL 设置为 __keyevent@0__:expired。通过这种方式,订阅者可以明确订阅在 Redis 配置中设置的 EXPIRED 密钥通知,并在CONFIG SET redis-cli 命令中使用KEx参数值。我们也可以使用 __keyevent@0__:*订阅所有按键事件,例如,如果您将 Redis 设置为在 Redis 配置中使用KEg参数设置的通用按键通知触发事件。
请注意,关于__keyevent@0__:expired中0的说明:0代表你所使用对应的redis库,如果您使用的是1库这里改为1即可,redis库图如下:
![](https://img-blog.csdnimg.cn/img_convert/4ecbe0bb01eac33bf21db60d3aef8f4b.png)
控制台测试结果如下:
![](https://img-blog.csdnimg.cn/img_convert/4cb748daac168a17ca815299eb729251.png)
EXPIRED:key,即为5秒后key过期收到的通知。
此功能需要redis2.8.0及以上版本,有更好的方案请留言或私信我吧。