目錄
一 、功能概覽
二、事件類型
三、設定
三、案例
代码
新增和修改都是set指令
删除
过期
首頁 資料庫 Redis SpringBoot怎麼監聽redis Key變化事件

SpringBoot怎麼監聽redis Key變化事件

May 26, 2023 pm 01:55 PM
redis springboot key

一 、功能概覽

鍵空間通知使得客戶端可以透過訂閱頻道或模式, 來接收那些以某種方式改變了 Redis key變化的事件。

所有修改key鍵的指令。

所有接收到 LPUSH key value [value …] 指令的鍵。

db資料庫中所有已過期的鍵。

事件透過Redis 的訂閱與發布功能(pub/sub)來進行分發, 因此所有支援訂閱與發布功能的用戶端都可以在無須做任何修改的情況下, 直接使用鍵空間通知功能。

因為Redis 目前的訂閱與發布功能採取的是發送即忘(fire and forget)策略, 所以如果你的程式需要可靠事件通知(reliable notification of events), 那麼目前的鍵空間通知可能不適合你: 當訂閱事件的客戶端斷線時, 它會失去所有在斷線期間分發給它的事件。

未來將會支援更可靠的事件分發, 這種支援可能會透過讓訂閱與發布功能本身變得更可靠來實現, 也可能會在Lua 腳本中對訊息(message)的訂閱與發布進行監聽, 從而實現類似將事件推入到列表這樣的操作。

二、事件類型

對於每個修改資料庫的操作,鍵空間通知都會傳送兩種不同類型的事件。

比如說,對 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 的參數可以是以下字元的任意組合, 它指定了伺服器該發送哪些類型的通知:

SpringBoot怎麼監聽redis Key變化事件

輸入的參數中至少要有一個 K或 E , 否則的話, 不管其餘的參數是什麼, 都不會有任何通知被分發。

舉個例子, 如果只想訂閱鍵空間中和列表相關的通知, 那麼參數就應該設為 Kl ,諸如此類。

將參數設為字串"AKE" 表示發送所有類型的通知。

每當一個鍵因為過期而被刪除時,產生一個 expired 通知。

每當一個鍵因為maxmemory政策而被刪除以回收記憶體時,產生一個 evicted 通知。

所有指令都只在鍵真的被改動了之後,才會產生通知。

比如說,當 SREM key member [member …]試圖刪除不存在於集合的元素時,刪除操作會執行失敗,因為沒有真正的改動鍵,所以這一操作不會發送通知。

如果對命令所產生的通知有疑問, 最好還是使用以下命令, 自己來驗證一下:

Redis 使用以下兩種方式刪除過期的鍵:

當一個鍵被存取時,程式會對這個鍵進行檢查,如果鍵已經過期,那麼該鍵將會被刪除。

底層系統會在後台漸進地尋找並刪除那些過期的鍵,從而處理那些已經過期、但是不會被存取到的鍵。
當過期鍵被以上兩個程式的任意一個發現、 並且將鍵從資料庫中刪除時, Redis 會產生一個 expired 通知。

Redis 不保證生存時間(TTL)變成0 的鍵會立即被刪除: 如果程式沒有存取這個過期鍵, 或帶有生存時間的鍵非常多的話, 那麼在鍵的生存時間變為0 , 直到鍵真正被刪除這中間, 可能會有一段比較顯著的時間間隔。

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

三、案例

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

连接到redis 输入一下命令

SpringBoot怎麼監聽redis Key變化事件

config set notify-keyspace-events KEA
登入後複製

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

SpringBoot怎麼監聽redis Key變化事件

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

创建一个 key :name valus:zhangsan

set name wsl
登入後複製
登入後複製

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

SpringBoot怎麼監聽redis 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;
    }
 
 
}
登入後複製

新增和修改都是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 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 在控制台可以看到已经收到消息了。

SpringBoot怎麼監聽redis Key變化事件

过期

如上面的操作方式一样

@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 Key變化事件

以上是SpringBoot怎麼監聽redis Key變化事件的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

redis集群模式怎麼搭建 redis集群模式怎麼搭建 Apr 10, 2025 pm 10:15 PM

Redis集群模式通過分片將Redis實例部署到多個服務器,提高可擴展性和可用性。搭建步驟如下:創建奇數個Redis實例,端口不同;創建3個sentinel實例,監控Redis實例並進行故障轉移;配置sentinel配置文件,添加監控Redis實例信息和故障轉移設置;配置Redis實例配置文件,啟用集群模式並指定集群信息文件路徑;創建nodes.conf文件,包含各Redis實例的信息;啟動集群,執行create命令創建集群並指定副本數量;登錄集群執行CLUSTER INFO命令驗證集群狀態;使

redis指令怎麼用 redis指令怎麼用 Apr 10, 2025 pm 08:45 PM

使用 Redis 指令需要以下步驟:打開 Redis 客戶端。輸入指令(動詞 鍵 值)。提供所需參數(因指令而異)。按 Enter 執行指令。 Redis 返迴響應,指示操作結果(通常為 OK 或 -ERR)。

redis怎麼啟動服務器 redis怎麼啟動服務器 Apr 10, 2025 pm 08:12 PM

啟動 Redis 服務器的步驟包括:根據操作系統安裝 Redis。通過 redis-server(Linux/macOS)或 redis-server.exe(Windows)啟動 Redis 服務。使用 redis-cli ping(Linux/macOS)或 redis-cli.exe ping(Windows)命令檢查服務狀態。使用 Redis 客戶端,如 redis-cli、Python 或 Node.js,訪問服務器。

redis怎麼查看所有的key redis怎麼查看所有的key Apr 10, 2025 pm 07:15 PM

要查看 Redis 中的所有鍵,共有三種方法:使用 KEYS 命令返回所有匹配指定模式的鍵;使用 SCAN 命令迭代鍵並返回一組鍵;使用 INFO 命令獲取鍵的總數。

redis底層怎麼實現 redis底層怎麼實現 Apr 10, 2025 pm 07:21 PM

Redis 使用哈希表存儲數據,支持字符串、列表、哈希表、集合和有序集合等數據結構。 Redis 通過快照 (RDB) 和追加只寫 (AOF) 機制持久化數據。 Redis 使用主從復制來提高數據可用性。 Redis 使用單線程事件循環處理連接和命令,保證數據原子性和一致性。 Redis 為鍵設置過期時間,並使用 lazy 刪除機制刪除過期鍵。

redis怎麼讀源碼 redis怎麼讀源碼 Apr 10, 2025 pm 08:27 PM

理解 Redis 源碼的最佳方法是逐步進行:熟悉 Redis 基礎知識。選擇一個特定的模塊或功能作為起點。從模塊或功能的入口點開始,逐行查看代碼。通過函數調用鏈查看代碼。熟悉 Redis 使用的底層數據結構。識別 Redis 使用的算法。

redis怎麼使用鎖 redis怎麼使用鎖 Apr 10, 2025 pm 08:39 PM

使用Redis進行鎖操作需要通過SETNX命令獲取鎖,然後使用EXPIRE命令設置過期時間。具體步驟為:(1) 使用SETNX命令嘗試設置一個鍵值對;(2) 使用EXPIRE命令為鎖設置過期時間;(3) 當不再需要鎖時,使用DEL命令刪除該鎖。

redis怎麼讀取隊列 redis怎麼讀取隊列 Apr 10, 2025 pm 10:12 PM

要從 Redis 讀取隊列,需要獲取隊列名稱、使用 LPOP 命令讀取元素,並處理空隊列。具體步驟如下:獲取隊列名稱:以 "queue:" 前綴命名,如 "queue:my-queue"。使用 LPOP 命令:從隊列頭部彈出元素並返回其值,如 LPOP queue:my-queue。處理空隊列:如果隊列為空,LPOP 返回 nil,可先檢查隊列是否存在再讀取元素。

See all articles