如何筛选Redis键空间通知?基于Azure Cache for Redis与StackExchange.Redis
Redis键事件通知:如何在Redis端筛选特定前缀的键通知
背景
基于Azure Cache for Redis和StackExchange.Redis包使用Redis键事件通知系统,已完成基础配置:
- Redis通知选项设为
Eg$,可接收所有键的写入/删除通知 - 已通过以下代码成功接收通知:
var configurationOptions = ConfigurationOptions.Parse("<connection_string>"); _connectionMultiplexer = ConnectionMultiplexer.Connect(configurationOptions); // ... var subscriber = _connectionMultiplexer.GetSubscriber(); subscriber.Subscribe("__keyevent@0__:set", (_, key) => { _logger.LogWarning("Received '{CacheKey}'", key); });
当前采用客户端过滤方案(仅处理前缀为my.key的键),但因Redis实例为多服务共享,会接收大量无关通知,性能不佳:
subscriber.Subscribe("__keyevent@0__:set", (_, key) => { if(!key.StartsWith("my.key")) return; _logger.LogWarning("Received '{CacheKey}'", key); });
尝试订阅"__keyevent@0__:set my.key*"无效,希望了解是否可通过Redis端指定筛选规则减少无关通知。
解决方案
Redis原生的键事件通知(__keyevent@<db>__:<command>)不支持直接在订阅时附加键前缀筛选,因为这类通知的订阅通道是按命令类型划分的,无法匹配键名规则。但可以通过**键空间通知+模式订阅(PSUBSCRIBE)**实现Redis端的前缀过滤:
步骤1:调整Redis通知配置
将Redis通知选项修改为Kg$(或KEg$,同时保留键事件和键空间通知):
K:启用键空间通知g:启用通用命令通知(如DEL、EXPIRE等)$:启用字符串命令通知(如SET、INCR等)
步骤2:使用模式订阅匹配键前缀
通过PSubscribe(模式订阅)订阅符合前缀的键空间通道,Redis会自动过滤掉不符合规则的通知,仅推送匹配的消息到客户端。示例代码:
var subscriber = _connectionMultiplexer.GetSubscriber(); // 订阅所有前缀为my.key的键的空间通知 subscriber.PSubscribe("__keyspace@0__:my.key*", (channel, command) => { // 从通道名中提取目标键:通道格式为 __keyspace@0__:my.key.xxx var cacheKey = channel.ToString().Split(':')[1]; // 根据触发的命令做处理,比如只关注SET操作 if (command == "set") { _logger.LogWarning("Received '{CacheKey}'", cacheKey); } });
关键说明
- 键空间通知与键事件通知的区别:
- 键事件通知(
__keyevent@<db>__:<command>):当执行指定命令时推送,消息内容是受影响的键名 - 键空间通知(
__keyspace@<db>__:<key>):当指定键发生变化时推送,消息内容是触发的命令名
- 键事件通知(
- 模式订阅(
PSUBSCRIBE)支持通配符匹配(*匹配任意字符、?匹配单个字符、[]匹配字符范围),Redis端会完成过滤,减少客户端的网络开销和处理负担
如果必须使用键事件通知,那么客户端过滤是唯一可行的方案,但性能不如Redis端过滤的键空间通知方案。
内容的提问来源于stack exchange,提问作者Kzryzstof
相关产品推荐
相关产品推荐

