キー スペース通知を使用すると、クライアントはチャネルまたはモードにサブスクライブすることで、何らかの方法で Redis キーを変更したイベントを受信できます。
キーを変更するすべてのコマンド。
LPUSH キー値 [値 …] コマンドを受け取るすべてのキー。
db データベース内の期限切れのキー。
イベントは Redis のサブスクリプションおよび公開機能 (pub/sub) を通じて配布されるため、サブスクリプションおよび公開機能をサポートするすべてのクライアントは、変更を加えずにキーを直接使用できます。
Redis の現在のサブスクリプションおよびパブリッシュ機能はファイア アンド フォーゲット戦略を採用しているため、プログラムで信頼性の高いイベント通知が必要な場合、現在のキー スペース通知は適切ではない可能性があります。イベントにサブスクライブしたクライアントが停止したときオフラインでは、切断中に配布されたすべてのイベントが失われます。
将来的には、より信頼性の高いイベント配信がサポートされる予定です。このサポートは、サブスクリプションおよびパブリッシング関数自体の信頼性を高めることによって、または Lua スクリプトでメッセージをサブスクライブおよびパブリッシュすることによって実現される可能性があります。パブリッシュして操作をリッスンするイベントをリストにプッシュするようなものです。
データベースを変更する操作ごとに、キースペース通知は 2 つの異なるタイプのイベントを送信します。
たとえば、データベース 0
のキー mykey
に対して DEL key [key …]
コマンドを実行すると、システムは2 つのメッセージ。これは、次の 2 つの PUBLISH チャネル メッセージ
コマンドを実行するのと同じです。
PUBLISH __keyspace@0__:mykey del PUBLISH __keyevent@0__:del mykey
最初のチャネルをサブスクライブします __keyspace@0__:mykey は、データベース内のすべての変更されたキー mykey のイベントを受信できます いいえ. 0、2 番目のチャネルを購読すると、__keyevent@0__:del でデータベース 0 番の del コマンドを実行するすべてのキーを受け取ることができます。
キースペースで始まるチャネルはキースペース通知と呼ばれ、キーイベントで始まるチャネルはキーイベント通知と呼ばれます。
del mykey コマンドが実行されると:
キースペース チャネルのサブスクライバーは、実行されたイベントの名前 (この例では del ) を受け取ります。
キー イベント チャネルのサブスクライバーは、イベントが実行されたキーの名前 (この例では mykey ) を受け取ります。
キースペース通知機能をオンにするとCPUを必要とするため、デフォルト設定ではこの機能はオフになっています。
redis.conf ファイルを変更するか、CONFIG SET コマンドを直接使用して、キースペース通知機能をオンまたはオフにできます。
notify-keyspace-events オプションのパラメーターが空の文字列、機能はオフになります。
一方、パラメータが空文字列でない場合、この機能はオンになります。
notify-keyspace-events のパラメータには、サーバーが送信する通知の種類を指定する次の文字を任意に組み合わせできます:
Inputパラメータ 少なくとも 1 つの K
または E
が含まれている必要があります。そうでない場合、他のパラメータが何であっても、通知は配信されません。
たとえば、キースペース内のリストに関連する通知のみをサブスクライブしたい場合は、パラメーターを Kl
などに設定する必要があります。
パラメータを文字列に設定します。 "AKE"
は、すべての種類の通知を送信することを意味します。
すべてのコマンドは、キーが実際に変更された後にのみ通知を生成します。 たとえば、有効期限切れによりキーが削除されるたびに、
expired
通知が生成されます。maxmemory
ポリシーによりメモリを再利用するためにキーが削除されるたびに、
evicted通知を生成します。
SREM キー メンバー [メンバー ...hellip;] がコレクション内に存在しない要素を削除しようとすると、実際の変更が存在しないため、削除操作は失敗します。キーなので、この通知は操作に対して送信されません。
キーにアクセスすると、プログラムはキーをチェックし、キーの有効期限が切れている場合、キーは削除されます。 基盤となるシステムは、期限切れになったがアクセスされないキーを処理するために、バックグラウンドで期限切れのキーを徐々に見つけて削除します。Redis は、有効期間 (TTL) が 0 になったキーがすぐに削除されることを保証しません。プログラムがこの期限切れのキーにアクセスしない場合、または有効期間を持つキーが多すぎる場合、キーの有効期間は 0 になり、キーが実際に削除されるまでにかなりの時間がかかる場合があります。上記 2 つのプログラムのいずれかによって期限切れのキーが検出され、そのキーがデータベースから削除されると、Redis は期限切れの通知を生成します。
因此, 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 中国語 Web サイトの他の関連記事を参照してください。