Keyspace 알림을 사용하면 클라이언트가 채널이나 모드를 구독하여 어떤 방식으로든 Redis 키를 변경하는 이벤트를 수신할 수 있습니다.
키 키를 수정하는 모든 명령입니다.
LPUSH 키 값 [value …] 명령을 받는 모든 키입니다.
DB 데이터베이스의 모든 만료된 키.
이벤트는 Redis의 구독 및 게시 기능(pub/sub)을 통해 배포되므로 구독 및 게시 기능을 지원하는 모든 클라이언트는 아무런 수정 없이 바로 키스페이스 알림 기능을 사용할 수 있습니다.
Redis의 현재 구독 및 게시 기능은 실행 후 잊어버리는 전략을 채택하기 때문에 프로그램에 안정적인 이벤트 알림이 필요한 경우 현재 키 공간 알림이 적합하지 않을 수 있습니다. 이벤트를 구독하는 클라이언트의 연결이 끊어집니다. 연결 해제 기간 동안 배포된 모든 이벤트가 손실됩니다.
향후에는 구독 및 게시 기능 자체를 더욱 안정적으로 만들거나 Lua 스크립트에서 메시지 구독 및 게시를 모니터링하여 보다 안정적인 이벤트 배포가 지원될 수 있습니다. 목록.
데이터베이스를 수정하는 각 작업에 대해 키스페이스 알림은 두 가지 유형의 이벤트를 보냅니다.
예를 들어, 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 的参数可以是以下字符的任意组合, 它指定了服务器该发送哪些类型的通知:
输入的参数中至少要有一个 K
或者 E
, 否则的话, 不管其余的参数是什么, 都不会有任何通知被分发。
举个例子, 如果只想订阅键空间中和列表相关的通知, 那么参数就应该设为 Kl
, 诸如此类。
将参数设为字符串"AKE"
表示发送所有类型的通知。
每当一个键因为过期而被删除时,产生一个
expired
通知。每当一个键因为
maxmemory
政策而被删除以回收内存时,产生一个evicted
通知。
所有命令都只在键真的被改动了之后,才会产生通知。
比如说,当 SREM key member [member …]
config set notify-keyspace-events KEA
3. 구성
keyspace 채널 구독자는 실행된 이벤트의 이름(이 경우 del )을 받게 됩니다.
키 이벤트 채널의 구독자는 이벤트가 실행된 키의 이름(이 경우 mykey )을 받게 됩니다.
키 공간 알림 기능을 켜려면 약간의 CPU가 필요하기 때문에 기본 구성에서는 이 기능이 꺼져 있습니다.
🎜redis.conf 파일을 수정하여 키스페이스 알림 기능을 켜거나 끌 수 있으며, CONFIG SET 명령을 직접 사용할 수도 있습니다. 🎜🎜notify-keyspace-events 옵션의 매개변수가 빈 문자열인 경우 기능이 켜집니다. 끄다. 🎜🎜반면, 매개변수가 빈 문자열이 아닌 경우 해당 기능이 활성화됩니다. 🎜🎜notify-keyspace-events의 매개변수는 서버가 보내야 하는 알림 유형을 지정하는 다음 문자의 조합일 수 있습니다. 🎜🎜🎜🎜입력 매개변수에는K
또는 E</가 하나 이상 있어야 합니다. code>, 그렇지 않으면 나머지 매개변수에 관계없이 알림이 전달되지 않습니다. 🎜🎜예를 들어 키스페이스의 목록과 관련된 알림만 구독하려면 매개변수를 <code>Kl
로 설정해야 합니다. 🎜🎜모든 유형의 알림 전송을 나타내려면 매개변수를 "AKE"
문자열로 설정하세요. 🎜🎜🎜 만료로 인해 키가 삭제될 때마다 만료
알림이 생성됩니다. 🎜🎜maxmemory
정책으로 인해 메모리를 회수하기 위해 키가 삭제될 때마다 제거
알림을 생성합니다. 🎜🎜🎜모든 명령은 키가 실제로 변경된 후에만 알림을 생성합니다. 🎜🎜예를 들어 SREM 키 멤버 [member …]
가 컬렉션에 존재하지 않는 요소를 삭제하려고 하면 키에 대한 실제 변경 사항이 없기 때문에 삭제 작업이 실패하므로 이 작업은 알림을 보내지 않습니다. 🎜🎜명령으로 생성된 알림에 대해 질문이 있는 경우 다음 명령을 사용하여 직접 확인하는 것이 가장 좋습니다. 🎜🎜Redis는 다음 두 가지 방법을 사용하여 만료된 키를 삭제합니다. 🎜🎜🎜키에 액세스하면 프로그램은 이 키를 확인하고 키가 만료된 경우 키가 삭제됩니다. 🎜🎜기본 시스템은 만료되었지만 액세스할 수 없는 키를 처리하기 위해 백그라운드에서 만료된 키를 점진적으로 찾아 삭제합니다. 🎜위의 두 프로그램 중 하나에서 만료된 키가 발견되어 해당 키가 데이터베이스에서 삭제되면 Redis는 만료된 알림을 생성합니다. 🎜🎜🎜Redis는 TTL이 0이 된 키가 즉시 삭제된다는 것을 보장하지 않습니다. 프로그램이 만료된 키에 액세스하지 않거나 TTL이 포함된 키가 너무 많으면 키의 TTL이 0이 될 수 있습니다. 키가 실제로 삭제될 때까지 상당한 시간 간격이 필요합니다. 🎜因此, 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
三秒后就可以控制台打印了相关信息
위 내용은 SpringBoot가 Redis 키 변경 이벤트를 모니터링하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!