You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redis Spring Data监听指定key的hset事件失败,求正确配置方案

如何监听Redis指定Key的HSet命令事件?

问题描述

使用Spring Data Redis配置消息监听器时,希望仅监听前缀为SampleProj:Message:*的Key的hset命令事件,但当前配置能接收该Key的所有事件(如del、hset等),尝试多种PatternTopic模式均无效:

现有配置:

@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(
            RedisConnectionFactory connectionFactory,
            MyMessageListener myMessageListener) {
        RedisMessageListenerContainer listenerContainer = new RedisMessageListenerContainer();
        listenerContainer.setConnectionFactory(connectionFactory);
        listenerContainer.addMessageListener(myMessageListener,
                   new PatternTopic("__keyspace@*__:SampleProj:Message:*")); 
            return listenerContainer;
        }

尝试过的无效模式:

new PatternTopic("__keyevent*:hset SampleProj:Message:*")
new PatternTopic("__keyevent@*__:hset:SampleProj:Message:*"));
new PatternTopic("__keyevent@*__:hset SampleProj:Message:*"));

甚至尝试组合模式列表:

Arrays.asList(new PatternTopic("__keyevent@*__:hset SampleProj:Message:"),
new PatternTopic("__keyspace@*__:SampleProj:Message:* hset")));

解决方案

要实现仅监听指定Key的hset事件,需结合Redis的键空间/键事件通知机制,以及监听器内的过滤逻辑,以下两种方案均可实现:

方案1:监听键空间通知,在监听器内过滤命令

Redis的键空间通知频道格式为__keyspace@db__:key,消息内容为触发的命令名。保持原有频道订阅,在监听器中仅处理hset命令:

  1. 容器配置保持不变:
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(
            RedisConnectionFactory connectionFactory,
            MyMessageListener myMessageListener) {
        RedisMessageListenerContainer listenerContainer = new RedisMessageListenerContainer();
        listenerContainer.setConnectionFactory(connectionFactory);
        listenerContainer.addMessageListener(myMessageListener,
                   new PatternTopic("__keyspace@*__:SampleProj:Message:*")); 
            return listenerContainer;
        }
  1. 修改MyMessageListener的onMessage方法,过滤命令:
@Override
public void onMessage(Message message, byte[] pattern) {
    // 获取触发的命令
    String command = new String(message.getBody());
    // 仅处理hset命令
    if ("hset".equals(command)) {
        // 编写业务逻辑,可提取目标Key
        String targetKey = new String(message.getChannel()).split(":")[2];
        System.out.println("收到指定Key的hset事件:" + targetKey);
    }
}

方案2:监听键事件通知,在监听器内过滤Key

Redis的键事件通知频道格式为__keyevent@db__:command,消息内容为触发事件的Key名。订阅hset命令的事件频道,再在监听器中过滤符合前缀的Key:

  1. 修改容器配置,订阅hset的键事件频道:
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(
            RedisConnectionFactory connectionFactory,
            MyMessageListener myMessageListener) {
        RedisMessageListenerContainer listenerContainer = new RedisMessageListenerContainer();
        listenerContainer.setConnectionFactory(connectionFactory);
        // 订阅所有数据库的hset命令事件
        listenerContainer.addMessageListener(myMessageListener,
                   new PatternTopic("__keyevent@*__:hset")); 
            return listenerContainer;
        }
  1. 修改MyMessageListener的onMessage方法,过滤Key:
@Override
public void onMessage(Message message, byte[] pattern) {
    // 获取触发事件的Key
    String key = new String(message.getBody());
    // 仅处理前缀为SampleProj:Message:*的Key
    if (key.startsWith("SampleProj:Message:")) {
        // 编写业务逻辑
        System.out.println("收到指定Key的hset事件:" + key);
    }
}

关键注意事项

  1. Redis服务器配置:必须确保Redis开启了键空间/键事件通知,修改Redis配置文件(redis.conf)中的notify-keyspace-events参数,例如设置为EA(E表示开启键事件通知,A表示监听所有命令)或EH(仅监听哈希相关命令)。若使用Spring Boot,可在application.properties中配置:
spring.redis.notify-keyspace-events=EA
  1. 无效模式原因:Redis的订阅频道格式是固定的,键事件频道仅支持__keyevent@db__:command格式,键空间频道仅支持__keyspace@db__:key格式,无法直接在频道中同时指定命令和Key,因此之前尝试的混合模式均无法生效。

内容的提问来源于stack exchange,提问作者Prabhakaran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 14:53:19