>  기사  >  데이터 베이스  >  SpringBoot가 Redis 키 변경 이벤트를 모니터링하는 방법

SpringBoot가 Redis 키 변경 이벤트를 모니터링하는 방법

PHPz
PHPz앞으로
2023-05-26 13:55:262254검색

1. 기능 개요

Keyspace 알림을 사용하면 클라이언트가 채널이나 모드를 구독하여 어떤 방식으로든 Redis 키를 변경하는 이벤트를 수신할 수 있습니다.

키 키를 수정하는 모든 명령입니다.

LPUSH 키 값 [value …] 명령을 받는 모든 키입니다.

DB 데이터베이스의 모든 만료된 키.

이벤트는 Redis의 구독 및 게시 기능(pub/sub)을 통해 배포되므로 구독 및 게시 기능을 지원하는 모든 클라이언트는 아무런 수정 없이 바로 키스페이스 알림 기능을 사용할 수 있습니다.

Redis의 현재 구독 및 게시 기능은 실행 후 잊어버리는 전략을 채택하기 때문에 프로그램에 안정적인 이벤트 알림이 필요한 경우 현재 키 공간 알림이 적합하지 않을 수 있습니다. 이벤트를 구독하는 클라이언트의 연결이 끊어집니다. 연결 해제 기간 동안 배포된 모든 이벤트가 손실됩니다.

향후에는 구독 및 게시 기능 자체를 더욱 안정적으로 만들거나 Lua 스크립트에서 메시지 구독 및 게시를 모니터링하여 보다 안정적인 이벤트 배포가 지원될 수 있습니다. 목록.

2. 이벤트 유형

데이터베이스를 수정하는 각 작업에 대해 키스페이스 알림은 두 가지 유형의 이벤트를 보냅니다.

예를 들어, 0 번호의 데이터베이스의 mykey 키에 대해 DEL key [key …] 명령을 실행하면 시스템은 두 개의 메시지를 배포합니다. 이는 다음 두 개의 PUBLISH 채널 메시지 명령을 실행하는 것과 동일합니다. 0 号数据库的键 mykey 执行 DEL key [key …]命令时, 系统将分发两条消息, 相当于执行以下两个 PUBLISH channel message 命令:

PUBLISH __keyspace@0__:mykey del
PUBLISH __keyevent@0__:del mykey

订阅第一个频道 __keyspace@0__:mykey 可以接收 0 号数据库中所有修改键 mykey 的事件, 而订阅第二个频道 __keyevent@0__:del则可以接收 0 号数据库中所有执行 del 命令的键。

以 keyspace 为前缀的频道被称为键空间通知(key-space notification), 而以 keyevent 为前缀的频道则被称为键事件通知(key-event notification)。

当 del mykey 命令执行时:

  • 键空间频道的订阅者将接收到被执行的事件的名字,在这个例子中,就是 del 。

  • 键事件频道的订阅者将接收到被执行事件的键的名字,在这个例子中,就是 mykey 。

三、配置

因为开启键空间通知功能需要消耗一些 CPU , 所以在默认配置下, 该功能处于关闭状态。

可以通过修改 redis.conf 文件, 或者直接使用 CONFIG SET 命令来开启或关闭键空间通知功能:

当 notify-keyspace-events 选项的参数为空字符串时,功能关闭。

另一方面,当参数不是空字符串时,功能开启。

notify-keyspace-events 的参数可以是以下字符的任意组合, 它指定了服务器该发送哪些类型的通知:

SpringBoot가 Redis 키 변경 이벤트를 모니터링하는 방법

输入的参数中至少要有一个 K或者 E , 否则的话, 不管其余的参数是什么, 都不会有任何通知被分发。

举个例子, 如果只想订阅键空间中和列表相关的通知, 那么参数就应该设为 Kl , 诸如此类。

将参数设为字符串"AKE" 表示发送所有类型的通知。

每当一个键因为过期而被删除时,产生一个 expired 通知。

每当一个键因为maxmemory政策而被删除以回收内存时,产生一个 evicted 通知。

所有命令都只在键真的被改动了之后,才会产生通知。

比如说,当 SREM key member [member …]

config set notify-keyspace-events KEA

첫 번째 채널 __keyspace@0__:mykey를 구독하면 데이터베이스 0번에서 수정된 모든 키 mykey의 이벤트를 수신할 수 있습니다. 두 번째 채널을 구독하면 __keyevent@0__:del 채널은 0번 데이터베이스에서 del 명령을 실행하는 모든 키를 수신할 수 있습니다.

키스페이스라는 접두사가 붙은 채널을 키스페이스 알림이라고 하며, 키이벤트라는 접두사가 붙은 채널을 키 이벤트 알림이라고 합니다.

del mykey 명령이 실행될 때:
  • keyspace 채널 구독자는 실행된 이벤트의 이름(이 경우 del )을 받게 됩니다.

  • 키 이벤트 채널의 구독자는 이벤트가 실행된 키의 이름(이 경우 mykey )을 받게 됩니다.

3. 구성

키 공간 알림 기능을 켜려면 약간의 CPU가 필요하기 때문에 기본 구성에서는 이 기능이 꺼져 있습니다.

🎜redis.conf 파일을 수정하여 키스페이스 알림 기능을 켜거나 끌 수 있으며, CONFIG SET 명령을 직접 사용할 수도 있습니다. 🎜🎜notify-keyspace-events 옵션의 매개변수가 빈 문자열인 경우 기능이 켜집니다. 끄다. 🎜🎜반면, 매개변수가 빈 문자열이 아닌 경우 해당 기능이 활성화됩니다. 🎜🎜notify-keyspace-events의 매개변수는 서버가 보내야 하는 알림 유형을 지정하는 다음 문자의 조합일 수 있습니다. 🎜🎜SpringBoot는 redis 키 변경 이벤트를 어떻게 모니터링합니까?🎜🎜입력 매개변수에는 K 또는 E가 하나 이상 있어야 합니다. code>, 그렇지 않으면 나머지 매개변수에 관계없이 알림이 전달되지 않습니다. 🎜🎜예를 들어 키스페이스의 목록과 관련된 알림만 구독하려면 매개변수를 <code>Kl로 설정해야 합니다. 🎜🎜모든 유형의 알림 전송을 나타내려면 매개변수를 "AKE" 문자열로 설정하세요. 🎜🎜🎜 만료로 인해 키가 삭제될 때마다 만료 알림이 생성됩니다. 🎜🎜maxmemory 정책으로 인해 메모리를 회수하기 위해 키가 삭제될 때마다 제거 알림을 생성합니다. 🎜🎜🎜모든 명령은 키가 실제로 변경된 후에만 알림을 생성합니다. 🎜🎜예를 들어 SREM 키 멤버 [member …]가 컬렉션에 존재하지 않는 요소를 삭제하려고 하면 키에 대한 실제 변경 사항이 없기 때문에 삭제 작업이 실패하므로 이 작업은 알림을 보내지 않습니다. 🎜🎜명령으로 생성된 알림에 대해 질문이 있는 경우 다음 명령을 사용하여 직접 확인하는 것이 가장 좋습니다. 🎜🎜Redis는 다음 두 가지 방법을 사용하여 만료된 키를 삭제합니다. 🎜🎜🎜키에 액세스하면 프로그램은 이 키를 확인하고 키가 만료된 경우 키가 삭제됩니다. 🎜🎜기본 시스템은 만료되었지만 액세스할 수 없는 키를 처리하기 위해 백그라운드에서 만료된 키를 점진적으로 찾아 삭제합니다. 🎜위의 두 프로그램 중 하나에서 만료된 키가 발견되어 해당 키가 데이터베이스에서 삭제되면 Redis는 만료된 알림을 생성합니다. 🎜🎜🎜Redis는 TTL이 0이 된 키가 즉시 삭제된다는 것을 보장하지 않습니다. 프로그램이 만료된 키에 액세스하지 않거나 TTL이 포함된 키가 너무 많으면 키의 TTL이 0이 될 수 있습니다. 키가 실제로 삭제될 때까지 상당한 시간 간격이 필요합니다. 🎜

因此, Redis 产生expired通知的时间为过期键被删除的时候, 而不是键的生存时间变为 0 的时候。

三、案例

按上文内容,我们先将redis的键空间通知开启,我们开启所有的通知,在可以端中测试后没问题再到代码中测试。

连接到redis 输入一下命令

SpringBoot가 Redis 키 변경 이벤트를 모니터링하는 방법

config set notify-keyspace-events KEA

  订阅键空间和键事件的主题

SpringBoot가 Redis 키 변경 이벤트를 모니터링하는 방법

psubscribe &#39;__key*__:*&#39;#对所有库键空间通知
 
psubscribe &#39;__keyspace@2__:*&#39; #是对db2数据库键空间通知
 
psubscribe &#39;__keyspace@2__:order*&#39; #是对db2数据库,key前缀为order所有键的键空间通知

创建一个 key :name valus:zhangsan

set name wsl

观察订阅的窗口 会受到两个消息,第一个是:键空间 第二个是键事件,键空间是内容是操作指令,主题中包含有key,键事件主题中包含了指令,内容是key。

SpringBoot가 Redis 키 변경 이벤트를 모니터링하는 방법

到这里说明已经开启了键空间通知

代码

以下代码采用string类型演示

在配置一下MessageListenerContainer类,将我们写好的监听类添加到该类中即可,删除和过期都是需要添加,我这里就一起添加了后面就不做演示。

@Configuration
public class RedisConfig {
 
    @Autowired
    private RedisTemplate redisTemplate;
 
    @Autowired
    private RedisUpdateAndAddListener redisUpdateAndAddListener;
 
    @Autowired
    private RedisDeleteListener redisDeleteListener;
 
    @Autowired
    private RedisExpiredListener redisExpiredListener;
 
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        //监听所有的key的set事件
        container.addMessageListener(redisUpdateAndAddListener, redisUpdateAndAddListener.getTopic());
        //监听所有key的删除事件
        container.addMessageListener(redisDeleteListener,redisDeleteListener.getTopic());
        //监听所有key的过期事件
        container.addMessageListener(redisExpiredListener,redisExpiredListener.getTopic());
        return container;
    }
 
 
}

新增和修改都是set指令

所以监听的主题都一样,实现MessageListener接口,重写onMessage这里就是收到消息的处理逻辑

@Component
@Data
public class RedisUpdateAndAddListener implements MessageListener {
	//监听的主题
    private  final PatternTopic topic = new PatternTopic("__keyevent@*__:set");
 
    @Override
    public void onMessage(Message message,byte[] pattern){
        String topic = new String(pattern);
        String msg = new String(message.getBody());
        System.out.println("收到key更新或修改,消息主题是:"+ topic+",消息内容是:"+msg);
    }
 
}

在redis中对name这个key进行set操作

set name wsl

在控制台就可以看到name这个key被操作了

SpringBoot가 Redis 키 변경 이벤트를 모니터링하는 방법

删除

跟上面的更新监听一样,只需要把订阅主题更改一下即可。同样需要添加到这个RedisMessageListenerContainer,上面已经添加,这里不做演示

@Component
@Data
public class RedisDeleteListener implements MessageListener {
 
    //监听主题
    private  final PatternTopic topic = new PatternTopic("__keyevent@*__:del");
 
    /**
     *
     * @param message 消息
     * @param pattern 主题
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
        String topic = new String(pattern);
        String msg = new String(message.getBody());
        System.out.println("收到key的删除,消息主题是:"+ topic+",消息内容是:"+msg);
    }
}

 在redis输入命令,del name 在控制台可以看到已经收到消息了。

SpringBoot가 Redis 키 변경 이벤트를 모니터링하는 방법

过期

如上面的操作方式一样

@Data
@Component
public class RedisExpiredListener implements MessageListener {
 
    //监听主题
    private  final PatternTopic topic = new PatternTopic("__keyevent@*__:expired");
 
    @Override
    public void onMessage(Message message, byte[] pattern) {
        String topic = new String(pattern);
        String msg = new String(message.getBody());
        System.out.println("收到key的过期,消息主题是:"+ topic+",消息内容是:"+msg);
    }
}

 在redis中写一个定时删除的keySETEX age 18 3三秒后就可以控制台打印了相关信息

SpringBoot가 Redis 키 변경 이벤트를 모니터링하는 방법

위 내용은 SpringBoot가 Redis 키 변경 이벤트를 모니터링하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제