ホームページ  >  記事  >  データベース  >  SpringBoot が Redis キー変更イベントを監視する方法

SpringBoot が Redis キー変更イベントを監視する方法

PHPz
PHPz転載
2023-05-26 13:55:262254ブラウズ

1. 機能の概要

キー スペース通知を使用すると、クライアントはチャネルまたはモードにサブスクライブすることで、何らかの方法で Redis キーを変更したイベントを受信できます。

キーを変更するすべてのコマンド。

LPUSH キー値 [値 …] コマンドを受け取るすべてのキー。

db データベース内の期限切れのキー。

イベントは Redis のサブスクリプションおよび公開機能 (pub/sub) を通じて配布されるため、サブスクリプションおよび公開機能をサポートするすべてのクライアントは、変更を加えずにキーを直接使用できます。

Redis の現在のサブスクリプションおよびパブリッシュ機能はファイア アンド フォーゲット戦略を採用しているため、プログラムで信頼性の高いイベント通知が必要な場合、現在のキー スペース通知は適切ではない可能性があります。イベントにサブスクライブしたクライアントが停止したときオフラインでは、切断中に配布されたすべてのイベントが失われます。

将来的には、より信頼性の高いイベント配信がサポートされる予定です。このサポートは、サブスクリプションおよびパブリッシング関数自体の信頼性を高めることによって、または Lua スクリプトでメッセージをサブスクライブおよびパブリッシュすることによって実現される可能性があります。パブリッシュして操作をリッスンするイベントをリストにプッシュするようなものです。

2. イベント タイプ

データベースを変更する操作ごとに、キースペース通知は 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 ) を受け取ります。

3. 設定

キースペース通知機能をオンにするとCPUを必要とするため、デフォルト設定ではこの機能はオフになっています。

redis.conf ファイルを変更するか、CONFIG SET コマンドを直接使用して、キースペース通知機能をオンまたはオフにできます。

notify-keyspace-events オプションのパラメーターが空の文字列、機能はオフになります。

一方、パラメータが空文字列でない場合、この機能はオンになります。

notify-keyspace-events のパラメータには、サーバーが送信する通知の種類を指定する次の文字を任意に組み合わせできます:

SpringBoot が Redis キー変更イベントを監視する方法

Inputパラメータ 少なくとも 1 つの K または E が含まれている必要があります。そうでない場合、他のパラメータが何であっても、通知は配信されません。

たとえば、キースペース内のリストに関連する通知のみをサブスクライブしたい場合は、パラメーターを Kl などに設定する必要があります。

パラメータを文字列に設定します。 "AKE" は、すべての種類の通知を送信することを意味します。

有効期限切れによりキーが削除されるたびに、expired 通知が生成されます。

maxmemory ポリシーによりメモリを再利用するためにキーが削除されるたびに、evicted 通知を生成します。

すべてのコマンドは、キーが実際に変更された後にのみ通知を生成します。

たとえば、

SREM キー メンバー [メンバー ...hellip;] がコレクション内に存在しない要素を削除しようとすると、実際の変更が存在しないため、削除操作は失敗します。キーなので、この通知は操作に対して送信されません。

コマンドによって生成された通知について質問がある場合は、次のコマンドを使用して自分で確認することをお勧めします。

Redis は、次の 2 つの方法を使用して期限切れのキーを削除します。

キーにアクセスすると、プログラムはキーをチェックし、キーの有効期限が切れている場合、キーは削除されます。

基盤となるシステムは、期限切れになったがアクセスされないキーを処理するために、バックグラウンドで期限切れのキーを徐々に見つけて削除します。

上記 2 つのプログラムのいずれかによって期限切れのキーが検出され、そのキーがデータベースから削除されると、Redis は期限切れの通知を生成します。

Redis は、有効期間 (TTL) が 0 になったキーがすぐに削除されることを保証しません。プログラムがこの期限切れのキーにアクセスしない場合、または有効期間を持つキーが多すぎる場合、キーの有効期間は 0 になり、キーが実際に削除されるまでにかなりの時間がかかる場合があります。

因此, Redis 产生expired通知的时间为过期键被删除的时候, 而不是键的生存时间变为 0 的时候。

三、案例

按上文内容,我们先将redis的键空间通知开启,我们开启所有的通知,在可以端中测试后没问题再到代码中测试。

连接到redis 输入一下命令

SpringBoot が Redis キー変更イベントを監視する方法

config set notify-keyspace-events KEA

  订阅键空间和键事件的主题

SpringBoot が Redis キー変更イベントを監視する方法

psubscribe '__key*__:*'#对所有库键空间通知
 
psubscribe '__keyspace@2__:*' #是对db2数据库键空间通知
 
psubscribe '__keyspace@2__:order*' #是对db2数据库,key前缀为order所有键的键空间通知

创建一个 key :name valus:zhangsan

set name wsl

观察订阅的窗口 会受到两个消息,第一个是:键空间 第二个是键事件,键空间是内容是操作指令,主题中包含有key,键事件主题中包含了指令,内容是key。

SpringBoot が Redis キー変更イベントを監視する方法

到这里说明已经开启了键空间通知

代码

以下代码采用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;
    }
 
 
}

新增和修改都是set指令

所以监听的主题都一样,实现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被操作了

SpringBoot が Redis キー変更イベントを監視する方法

删除

跟上面的更新监听一样,只需要把订阅主题更改一下即可。同样需要添加到这个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 在控制台可以看到已经收到消息了。

SpringBoot が Redis キー変更イベントを監視する方法

过期

如上面的操作方式一样

@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 キー変更イベントを監視する方法

以上がSpringBoot が Redis キー変更イベントを監視する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。