Key space notification allows the client to receive events that have changed the Redis key in some way by subscribing to the channel or mode.
All commands that modify key keys.
All keys that receive the LPUSH key value [value …] command.
All expired keys in the db database.
Events are distributed through the subscription and publishing functions (pub/sub) of Redis, so all clients that support the subscription and publishing functions can directly use the key without making any modifications. Space notification function.
Because the current subscription and publishing functions of Redis adopt a fire and forget strategy, if your program requires reliable notification of events, then the current key space notification may Not suitable for you: When a client subscribed to events goes offline, it loses all events that were distributed to it during the disconnection.
In the future, more reliable event distribution will be supported. This support may be achieved by making the subscription and publishing functions themselves more reliable, or by subscribing and publishing messages in Lua scripts. Publish to listen to achieve operations like pushing events to a list.
For each operation that modifies the database, keyspace notifications will send two different types of events.
For example, when executing the DEL key [key …]
command on the key mykey
of database 0
, the system will distribute two message, which is equivalent to executing the following two PUBLISH channel message
commands:
PUBLISH __keyspace@0__:mykey del PUBLISH __keyevent@0__:del mykey
Subscribing to the first channel __keyspace@0__:mykey can receive events for all modified keys mykey in database No. 0, Subscribing to the second channel __keyevent@0__:del can receive all keys that execute the del command in database No. 0.
The channel prefixed by keyspace is called key-space notification, and the channel prefixed by keyevent is called key-event notification.
When the del mykey command is executed:
Subscribers to the keyspace channel will receive the name of the event that was executed, in this example, del .
Subscribers to the key event channel will receive the name of the key for which the event was executed, in this example, mykey .
Because turning on the key space notification function requires some CPU, so in the default configuration, this function is turned off.
You can turn on or off the keyspace notification function by modifying the redis.conf file or directly using the CONFIG SET command:
When the parameter of the notify-keyspace-events option is an empty string, Function is turned off.
On the other hand, when the parameter is not an empty string, the function is turned on.
The parameters of notify-keyspace-events can be any combination of the following characters, which specifies which types of notifications the server should send:
Input parameters There must be at least one K
or E
in it, otherwise, no matter what the other parameters are, no notification will be distributed.
For example, if you only want to subscribe to notifications related to lists in the keyspace, then the parameter should be set to Kl
, and so on.
Set the parameter to a string "AKE"
means sending all types of notifications.
Whenever a key is deleted due to expiration, an
expired
notification is generated.Generate an
evicted
notification whenever a key is deleted to reclaim memory due to themaxmemory
policy.
All commands will only generate notifications after the key has actually been changed.
For example, when SREM key member [member …hellip;]
attempts to delete an element that does not exist in the collection, the deletion operation will fail because there is no real change to the key, so this Notifications will not be sent for the operation.
If you have any questions about the notification generated by the command, it is best to use the following command to verify it yourself:
Redis uses the following two methods to delete expired keys:
When a key is accessed, the program will check the key. If the key has expired, the key will be deleted.
The underlying system will progressively find and delete expired keys in the background to process keys that have expired but will not be accessed.
When an expired key is discovered by either of the above two programs and the key is deleted from the database, Redis will generate an expired notification.
Redis does not guarantee that a key whose lifetime (TTL) becomes 0 will be deleted immediately: if the program does not access this expired key, or if there are too many keys with lifetime, then the key The lifetime becomes 0, and there may be a significant time interval between when the key is actually deleted.
因此, Redis 产生expired通知的时间为过期键被删除的时候, 而不是键的生存时间变为 0 的时候。
按上文内容,我们先将redis的键空间通知开启,我们开启所有的通知,在可以端中测试后没问题再到代码中测试。
连接到redis 输入一下命令
config set notify-keyspace-events KEA
订阅键空间和键事件的主题
psubscribe '__key*__:*'#对所有库键空间通知 psubscribe '__keyspace@2__:*' #是对db2数据库键空间通知 psubscribe '__keyspace@2__:order*' #是对db2数据库,key前缀为order所有键的键空间通知
创建一个 key :name valus:zhangsan
set name wsl
观察订阅的窗口 会受到两个消息,第一个是:键空间 第二个是键事件,键空间是内容是操作指令,主题中包含有key,键事件主题中包含了指令,内容是key。
到这里说明已经开启了键空间通知
以下代码采用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; } }
所以监听的主题都一样,实现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被操作了
跟上面的更新监听一样,只需要把订阅主题更改一下即可。同样需要添加到这个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
在控制台可以看到已经收到消息了。
如上面的操作方式一样
@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
三秒后就可以控制台打印了相关信息
The above is the detailed content of How SpringBoot monitors redis Key change events. For more information, please follow other related articles on the PHP Chinese website!