redis自2.8.0之後版本提供keyspace notifications功能,允許客戶訂閱pub / sub頻道,以便以某種方式接收影響redis資料集的事件。
可能收到的事件的例子如下:
所有影響給定鍵的命令。
所有接收lpush操作的金鑰。
所有金鑰在資料庫中過期0。
因為 redis 目前的訂閱與發布功能採取的是傳送即忘(fire and forget)策略, 所以如果你的程式需要可靠事件通知(reliable notification of events), 那麼目前的鍵空間通知可能並不適合你:當訂閱事件的客戶端斷線時, 它會丟失所有在斷線期間分發給它的事件。並不能確保訊息送達。未來有計畫允許更可靠的事件傳遞,但可能這將在更一般的層面上解決,或者為pub / sub本身帶來可靠性,或者允許lua指令碼攔截pub / sub訊息來執行諸如推送將事件列入清單。
對於每個修改資料庫的操作,鍵空間通知都會傳送兩種不同型別的事件訊息:keyspace 和 keyevent。以 keyspace 為字首的頻道被稱為鍵空間通知(key-space notification), 而以 keyevent 為字首的頻道則被稱為鍵事件通知(key-event notification)。
事件是用 __keyspace@db__:keypattern 或者 __keyevent@db__:opstype 的格式來發布訊息的。
db表示在第幾個庫;keypattern則是表示需要監控的鍵模式(可以用萬用字元,如:__key*__:*);opstype則表示操作型別。因此,如果想要訂閱特殊的key上的事件,應該是訂閱keyspace。
比如說,對 0 號資料庫的鍵 mykey 執行 del 命令時, 系統將分發兩條訊息, 相當於執行以下兩個 publish 命令:
publish __keyspace@0__:samplekey del
publish __keyevent@0__:del samplekey
訂閱第乙個頻道 __keyspace@0__:mykey 可以接收 0 號資料庫中所有修改鍵 mykey 的事件, 而訂閱第二個頻道 __keyevent@0__:del 則可以接收 0 號資料庫中所有執行 del 命令的鍵。
字元
傳送通知
k鍵空間通知,所有通知以keyspace@為字首,針對key
e鍵事件通知,所有通知以keyevent@為字首,針對event
gdel 、 expire 、 rename 等型別無關的通用命令的通知
$字串命令的通知
l列表命令的通知
s集合命令的通知
h雜湊命令的通知
z有序集合命令的通知
x過期事件:每當有過期鍵被刪除時傳送
e驅逐(evict)事件:每當有鍵因為 maxmemory 政策而被刪除時傳送
a引數 g$lshzxe 的別名,相當於是all
輸入的引數中至少要有乙個 k 或者 e , 否則的話, 不管其餘的引數是什麼, 都不會有任何通知被分發。上表中斜體的部分為通用的操作或者事件,而黑體則表示特定資料型別的操作。配置檔案中修改 notify-keyspace-events 「kx」,注意:這個雙引號是一定要的,否則配置不成功,啟動也不報錯。例如,「kx」表示想監控某個key的失效事件。
也可以通過config配置:config set notify-keyspace-events ex (但非持久化)
redis 使用以下兩種方式刪除過期的鍵:
1.當乙個鍵被訪問時,程式會對這個鍵進行檢查,如果鍵已經過期,那麼該鍵將被刪除。
2.底層系統會在後台查詢並刪除那些過期的鍵,從而處理那些已經過期、但是不會被訪問到的鍵。
當過期鍵被以上兩個程式的任意乙個發現、 並且將鍵從資料庫中刪除時, redis 會產生乙個 expired 通知。
因此, redis 產生 expired 通知的時間為過期鍵被刪除的時候, 而不是鍵的生存時間變為 0 的時候。
由於通知收到的是redis key,value已經過期,無法收到,所以需要在key上標記業務資料。
實現思路:
1,利用messagelisteneradapter,spring本身已經提供了的實現方式。
首先自定義乙個messagedelegate 介面並實現
1 public inte***ce mymessagedelegate
8 9 public class myrediskeyexpiredmessagedelegate implements messagedelegate
xml相關配置
具體可參考官方文件:
2.即自定義乙個keyexpiredlistener類繼承自jedispubsub。
import redis.clients.jedis.jedispubsub;
public class keyexpiredlistener extends jedispubsub
@override
public void onpmessage(string pattern, string channel, string message)
}
訂閱者
public class subscriber
}
測試
public class testjedis
}
結果
onpsubscribe __key*__:* 1
onpmessage pattern __key*__:* __keyevent@0__:expired sla_zw_line_lock_sssssss
onpmessage pattern __key*__:* __keyevent@0__:expired sla_zw_line_lock_sssssss
其中第一行的列印是啟動訂閱者的時候才列印1次
3,發布和訂閱的方式
特性介紹
pub/sub功能(means publish, subscribe)即發布及訂閱功能。基於事件的系統中,pub/sub是目前廣泛使用的通訊模型,它採用事件作為基本的通訊機制,提供大規模系統所要求的鬆散耦合的互動模式:訂閱者(如客戶端)以事件訂閱的方式表達出它有興趣接收的乙個事件或一類事件;發布者(如伺服器)可將訂閱者感興趣的事件隨時通知相關訂閱者。
監聽者
public class subscriberlistener extends jedispubsub
@override
public void onmessage(string channel, string message)
@override
public void onsubscribe(string channel, int subscribedchannels)
@override
public void onunsubscribe(string channel, int subscribedchannels)
}
發布者
public class publisher extends thread
@override
public void run() else
} catch (ioexception e)
}}
訂閱者
public class pubsubdemo
}
測試類
public class subthread extends thread
@override
public void run() catch (exception e) finally }}
}
測試結果
redis pool is starting, redis ip 127.0.0.1, redis port 6379
subscribe redis, channel mychannel, thread will be blocked
subscribe redis channel success, channel mychannel, subscribedchannels 1
mytest -------------我鍵入的值
receive redis published message, channel mychannel, message mytest
this is my second test -------------我鍵入的值
receive redis published message, channel mychannel, message this is my second test
redis 超時失效key 的監聽觸發
1.事件通過 redis 的訂閱與發布功能 pub sub 來進行分發,故需要訂 閱 keyevent 0 expired 通道 0表示db0 根據自己的dbindex選擇合適的數字 2.修改 redis.conf 檔案 修改 notify keyspace events ex k 鍵空間通知,以 ...
redis 超時失效key 的監聽觸發
1.事件通過 redis 的訂閱與發布功能 pub sub 來進行分發,故需要訂 閱 keyevent 0 expired 通道 0表示db0 根據自己的dbindex選擇合適的數字 2.修改 redis.conf 檔案 修改 notify keyspace events ex k 鍵空間通知,以 ...
Redis監聽Key失效
之前我使用過使用redisson這種redis的框架實現過延時傳送。今天突然好奇,在springboot中,redis能監聽到key失效事件嗎?經過查資料,答案是肯定的,可以監聽key失效,但是有缺陷,監聽事件裡面只能拿到key,不能拿到這個key對應的value。所以說,在生成這個key的時候,需...