Redis鍵空間通知(keyspace notification),事件訂閱
應用場景:有效期優惠券、24小時內支付、下單有效事件等等。
功能概覽
- 所有修改鍵的命令。
- 所有接收到 LPUSH key value [value …] 命令的鍵。
- 0 號數據庫中所有已過期的鍵。
- 鍵空間頻道的訂閱者將接收到被執行的事件的名字,在這個例子中,就是 del 。
- 鍵事件頻道的訂閱者將接收到被執行事件的鍵的名字,在這個例子中,就是 mykey 。
配置
- 當 notify-keyspace-events 選項的參數爲空字符串時,功能關閉。
- 另一方面,當參數不是空字符串時,功能開啓。
字符
|
發送的通知
|
K
|
鍵空間通知,所有通知以 __keyspace@<db>__ 爲前綴
|
E
|
鍵事件通知,所有通知以 __keyevent@<db>__ 爲前綴
|
g
|
DEL 、 EXPIRE 、 RENAME 等類型無關的通用命令的通知
|
$
|
字符串命令的通知
|
l
|
列表命令的通知
|
s
|
集合命令的通知
|
h
|
哈希命令的通知
|
z
|
有序集合命令的通知
|
x
|
過期事件:每當有過期鍵被刪除時發送
|
e
|
驅逐(evict)事件:每當有鍵因爲 maxmemory 政策而被刪除時發送
|
A
|
參數 g$lshzxe 的別名
|
命令產生的通知
- DEL key [key …] 命令爲每個被刪除的鍵產生一個 del 通知。
- RENAME key newkey 產生兩個通知:爲來源鍵(source key)產生一個 rename_from 通知,併爲目標鍵(destination key)產生一個 rename_to 通知。
- EXPIRE key seconds 和 EXPIREAT key timestamp 在鍵被正確設置過期時間時產生一個 expire 通知。當 EXPIREAT key timestamp 設置的時間已經過期,或者 EXPIRE key seconds傳入的時間爲負數值時,鍵被刪除,併產生一個 del 通知。
- SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern …]] [ASC | DESC] [ALPHA] [STORE destination] 在命令帶有 STORE 參數時產生一個 sortstore 事件。如果 STORE 指示的用於保存排序結果的鍵已經存在,那麼程序還會發送一個 del 事件。
- SET key value [EX seconds] [PX milliseconds] [NX|XX] 以及它的所有變種(SETEX key seconds value 、 SETNX key value 和 GETSET key value)都產生 set 通知。其中 SETEX key seconds value 還會產生 expire 通知。
- MSET key value [key value …] 爲每個鍵產生一個 set 通知。
- SETRANGE key offset value 產生一個 setrange 通知。
- INCR key 、 DECR key 、 INCRBY key increment 和 DECRBY key decrement 都產生 incrby通知。
- INCRBYFLOAT key increment 產生 incrbyfloat 通知。
- APPEND key value 產生 append 通知。
- LPUSH key value [value …] 和 LPUSHX key value 都產生單個 lpush 通知,即使有多個輸入元素時,也是如此。
- RPUSH key value [value …] 和 RPUSHX key value 都產生單個 rpush 通知,即使有多個輸入元素時,也是如此。
- RPOP key 產生 rpop 通知。如果被彈出的元素是列表的最後一個元素,那麼還會產生一個 del 通知。
- LPOP key 產生 lpop 通知。如果被彈出的元素是列表的最後一個元素,那麼還會產生一個 del 通知。
- LINSERT key BEFORE|AFTER pivot value 產生一個 linsert 通知。
- LSET key index value 產生一個 lset 通知。
- LTRIM key start stop 產生一個 ltrim 通知。如果 LTRIM key start stop 執行之後,列表鍵被清空,那麼還會產生一個 del 通知。
- RPOPLPUSH source destination 和 BRPOPLPUSH source destination timeout 產生一個 rpop 通知,以及一個 lpush 通知。兩個命令都會保證 rpop 的通知在 lpush 的通知之前分發。如果從鍵彈出元素之後,被彈出的列表鍵被清空,那麼還會產生一個 del 通知。
- HSET hash field value 、 HSETNX hash field value 和 HMSET 都只產生一個 hset 通知。
- HINCRBY 產生一個 hincrby 通知。
- HINCRBYFLOAT 產生一個 hincrbyfloat 通知。
- HDEL 產生一個 hdel 通知。如果執行 HDEL 之後,哈希鍵被清空,那麼還會產生一個 del 通知。
- SADD key member [member …] 產生一個 sadd 通知,即使有多個輸入元素時,也是如此。
- SREM key member [member …] 產生一個 srem 通知,如果執行 SREM key member [member …] 之後,集合鍵被清空,那麼還會產生一個 del 通知。
- SMOVE source destination member 爲來源鍵(source key)產生一個 srem 通知,併爲目標鍵(destination key)產生一個 sadd 事件。
- SPOP key 產生一個 spop 事件。如果執行 SPOP key 之後,集合鍵被清空,那麼還會產生一個 del 通知。
- SINTERSTORE destination key [key …] 、 SUNIONSTORE destination key [key …] 和 SDIFFSTORE destination key [key …] 分別產生 sinterstore 、 sunionostore 和 sdiffstore三種通知。如果用於保存結果的鍵已經存在,那麼還會產生一個 del 通知。
- ZINCRBY key increment member 產生一個 zincr 通知。(譯註:非對稱,請注意。)
- ZADD key score member [[score member] [score member] …] 產生一個 zadd 通知,即使有多個輸入元素時,也是如此。
- ZREM key member [member …] 產生一個 zrem 通知,即使有多個輸入元素時,也是如此。如果執行 ZREM key member [member …] 之後,有序集合鍵被清空,那麼還會產生一個 del 通知。
- ZREMRANGEBYSCORE key min max 產生一個 zrembyscore 通知。(譯註:非對稱,請注意。)如果用於保存結果的鍵已經存在,那麼還會產生一個 del 通知。
- ZREMRANGEBYRANK key start stop 產生一個 zrembyrank 通知。(譯註:非對稱,請注意。)如果用於保存結果的鍵已經存在,那麼還會產生一個 del 通知。
- ZINTERSTORE destination numkeys key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX] 和 ZUNIONSTORE destination numkeys key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX] 分別產生 zinterstore 和 zunionstore 兩種通知。如果用於保存結果的鍵已經存在,那麼還會產生一個 del 通知。
- 每當一個鍵因爲過期而被刪除時,產生一個 expired 通知。
- 每當一個鍵因爲 maxmemory 政策而被刪除以回收內存時,產生一個 evicted 通知。
配置具體說明:
- 首先找到redis.conf配置文件,打開文件,查找notify-keyspace-events,將前面的#去掉即可。注意:這裏配置的是notify-keyspace-events的Ex參數,即說明,當鍵過期的時候會觸發通知,如果只需要哈希命令鍵觸發通知則可以設置爲notify-keyspace-events Eh。
- 重啓redis-server。
- 配置完成。
代碼說明:
<?php class Redis2 { private $redis; public function __construct($host = '127.0.0.1', $port = 6379) { $this->redis = new Redis(); $this->redis->connect($host, $port); } public function setex($key, $time, $val) { return $this->redis->setex($key, $time, $val); } public function set($key, $val) { return $this->redis->set($key, $val); } public function get($key) { return $this->redis->get($key); } public function incr($key) { return $this->redis->incr($key); } public function expire($key = null, $time = 0) { return $this->redis->expire($key, $time); } public function psubscribe($patterns = array(), $callback) { $this->redis->psubscribe($patterns, $callback); } public function setOption() { $this->redis->setOption(\Redis::OPT_READ_TIMEOUT, -1); } }
<?php require_once './Redis.class.php'; $redis = new \Redis2(); // 解決Redis客戶端訂閱時候超時情況 $redis->setOption(); $redis->psubscribe(array('__keyevent@0__:incrby'), 'keyCallback'); // 回調函數,這裏寫處理邏輯 function keyCallback($redis, $pattern, $chan, $msg) { echo "Pattern: $pattern\n"; echo "Channel: $chan\n"; echo "Payload: $msg\n\n"; //keyCallback爲訂閱事件後的回調函數,這裏寫業務處理邏輯, //比如前面提到的商品不支付自動撤單,這裏就可以根據訂單id,來實現自動撤單 }
<?php require_once './Redis.class.php'; $redis = new \Redis2(); $var = 123; $redis->incr($var);
進行測試
- 運行psubscribe.php。
- 運行 index.php。
- 觀察訂閱狀態。如下。
- 事件觸發通知成功。