当前位置: 首页 > 工具软件 > Keyspace > 使用案例 >

redis的数据库通知(notify-keyspace-events)

东方富
2023-12-01

redis的数据库通知(notify-keyspace-events)

共分为两类:一类是键空间通知 另一类是键事件通知

概述

数据库通知是redis在2.8之后新增的功能,让客户端可以已发布/订阅模式来获取数据库中键的变化以及某事件的发生

  • 首先要知道这个发送通知的操作是占内存的,所以默认的关闭的,需要我们手动的在redis.conf里面进行开启
  • 如何开启:
    • 进入redis安装地址的/redis/etc文件下,vim redis.conf
    • 找到notify-keyspace-events,默认为“”,这里需要进行配置,配置完就开启了
    • K Keyspace events, published with keyspace@ prefix.
      E Keyevent events, published with keyevent@ 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.
    • K和E是必须要选一个配的,不行就配置AKE,表示所有的事件和键变化都会发送两条通知

开启后:

开启后能接收到的类型只有两种:keyspace和keyevent

前者为事件的具体操作,后者为事件影响的键名

  1. 数据库0中删除一个叫mykey的键 127.0.0.1:6379> del mykey
  2. 数据库0会发布下面两条信息:
    • public keyspace@0:mykey del (键空间信息,mykey键被删了)
    • public keyevent@0:del mykey (事件空间信息,执行了删除事件,删除了mykey)

redis发布后我们如何接受呢

项目中配置了redis.conf,redisListenerConfig之后

编写个 RedisKeyExpirationListenerServer 类继 KeyExpirationEventMessageListener

然后实现他的doRegister方法和onMessage方法

主要就是doRegister里面你进行订阅的topic是啥

  • 想要订阅键空间就是 __keyspace,具体哪个键就后面@再加上键的key,如user,key a,key b等等。
  • 想要订阅键事件就是__keyevent,具体哪个事件就后面@再加上事件的操作,如del ,set ,expire等

如何接收实例:

我的需求是当设置的某个键过期的时候,我这边能接收到这个事件,所以这里我接收的是keyevent@0__:expired这个topic

  • 监听类的doRegister和onmessage方法
  • doregister就是监听keyevent(键事件通知)中的expired事件
    • tring topic = “keyevent@“+database+”:expired”;
  • onMessage就是获取到这个过期的键的详情,直接message.toString就可以获取到这个过期键的key(这里要注意,message里面获取不到该过期键的value)
    • String expiredKey = message.toString();
 @Override
    protected void doRegister(RedisMessageListenerContainer listenerContainer) {
        String topic = "__keyevent@"+database+"__:expired";
        log.info("配置监听哪个频道:"+topic);

        PatternTopic patternTopic = new PatternTopic(topic);
        // 频道可以是多,多个传list
        listenerContainer.addMessageListener(this,patternTopic);
    }


    @Override
    public void onMessage(Message message, byte[] pattern) {
        // 用户做自己的业务处理即可,注意message.toString()可以获取失效的key
        String expiredKey = message.toString();
        log.info("失效的key"+expiredKey);
       if(expiredKey.contains(RedisContact.SERVERNAME)){
           deal(expiredKey);
       }
 类似资料: