Redis中监听key过期通知

前言

正常情况下,我们是不需要监听 key 是否过期的,毕竟项目中 key 数量可能成千上万,要监听的话很耗费服务器资源。但是如果项目中 key 数量很少,且我们要在指定 key 过期时告警,这种场景下就是合适的。

使用

服务器开启配置

redis.conf 文件

notify-keyspace-events Ex

默认配置为 "",表示未开启,Ex 表示 key 过期通知。

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, ...(通用命令(非类型特定的),如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)(驱逐事件(当为maxmemory退出一个键时生成的事件))
t     Stream commands(Stream命令)
d     Module key type events(模块key类型事件)
m     Key-miss events (Note: It is not included in the 'A' class)(Key-miss事件(当访问不存在的键时通知,不包含在A中))
A     Alias for g$lshzxetd(g$lshzxetd的别名都可用A表示), so that the "AKE" string means all the events(Except key-miss events which are excluded from 'A' due to their unique nature)(用“AKE”可表示所有事件通知,除了特殊的Key-miss事件)

代码配置

在 SpringBoot 项目中使用

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
spring:
  redis:
    host: ip
    port: 6379
    password: xxx

具体代码如下

@Configuration
public class RedisConfig {

    @Bean
    public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory) {
        // redis 消息订阅(监听者)容器
        RedisMessageListenerContainer messageListenerContainer = new RedisMessageListenerContainer();
        messageListenerContainer.setConnectionFactory(redisConnectionFactory);
        return messageListenerContainer;
    }

    @Bean
    public CustomRedisKeyExpirationListener customRedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        return new CustomRedisKeyExpirationListener(listenerContainer);
    }

    public static class CustomRedisKeyExpirationListener extends KeyExpirationEventMessageListener {

        public CustomRedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
            super(listenerContainer);
        }

        @Override
        protected void doHandleMessage(Message message) {
            String expiredKey = message.toString();
            System.out.println("监听到过期key: " + expiredKey);
        }
    }
}

通过 继承 KeyExpirationEventMessageListener 来实现,如果我们服务器没有配置 notify-keyspace-events,spring 会自动配置其值为 EA,具体参考 KeyspaceEventMessageListener 的 init() 方法。

监听器的底层原理为 redis 的发布订阅功能,当有 key 过期时,会向 keyevent@*:expired 这个 topic 发送消息,我们客户端监听此 topic,得到过期的 key,做相应的处理。

参考

Redis key过期监听
Redis键空间通知(Keyspace Notifications)
Redis键空间通知

posted @ 2024-04-03 19:12  strongmore  阅读(1243)  评论(0编辑  收藏  举报