redis發布訂閱及事務

2021-09-14 06:59:43 字數 3642 閱讀 2197

redis發布訂閱

例:訂閱者:

redis 127.0.0.1:6379> subscribe redischat

reading messages... (press ctrl-c to quit)

1) "subscribe"

2) "redischat"

3) (integer) 1

發布者:

redis 127.0.0.1:6379> publish redischat "redis is a great caching technique"

(integer) 1

redis 127.0.0.1:6379> publish redischat "learn redis by runoob.com"

(integer) 1

# 訂閱者的客戶端會顯示如下訊息

1) "message"

2) "redischat"

3) "redis is a great caching technique"

1) "message"

2) "redischat"

3) "learn redis by runoob.com"

要求訂閱china為字首的所有頻道:

psubscribe pattern [pattern ...]

訂閱乙個或多個符合給定模式的頻道。

每個模式以 * 作為匹配符,比如 it* 匹配所有以 it 開頭的頻道( it.news 、 it.blog 、 it.tweets 等等), news.* 匹配所有以 news. 開頭的頻道( news.it 、 news.global.today 等等),諸如此類。

退訂:使用 unsubscribe 命令可以退訂指定的頻道, 這個命令執行的是訂閱的反操作: 它從 pubsub_channels 字典的給定頻道(鍵)中, 刪除關於當前客戶端的資訊, 這樣被退訂頻道的資訊就不會再傳送給這個客戶端。

redis事務

以下是乙個事務的例子, 它先以 multi 開始乙個事務, 然後將多個命令入隊到事務中, 最後由 exec 命令觸發事務, 一併執行事務中的所有命令:

redis 127.0.0.1:6379> multi

okredis 127.0.0.1:6379> set book-name "mastering c++ in 21 days"

queued

redis 127.0.0.1:6379> get book-name

queued

redis 127.0.0.1:6379> sadd tag "c++" "programming" "mastering series"

queued

redis 127.0.0.1:6379> smembers tag

queued

redis 127.0.0.1:6379> exec

1) ok

2) "mastering c++ in 21 days"

3) (integer) 3

4) 1) "mastering series"

2) "c++"

3) "programming"

單個 redis 命令的執行是原子性的,但 redis 沒有在事務上增加任何維持原子性的機制,所以 redis 事務的執行並不是原子性的。

事務可以理解為乙個打包的批量執行指令碼,但批量指令並非原子化的操作,中間某條指令的失敗不會導致前面已做指令的回滾,也不會造成後續的指令不做。

discard              取消事務,放棄執行事務塊內的所有命令。

watch key [key ...]                  監視乙個(或多個) key ,如果在事務執行之前這個(或這些) key 被其他命令所改動,那麼事務將被打斷。

unwatch             取消 watch 命令對所有 key 的監視。

事務內部的錯誤:

在乙個事務的執行期間,可能會遇到兩種型別的命令錯誤:

乙個命令可能會在被放入佇列時失敗。因此,事務有可能在呼叫exec命令之前就發生錯誤。例如,這個命令可能會有語法錯誤(引數的數量錯誤、命令名稱錯誤,等等),或者可能會有某些臨界條件(例如:如果使用maxmemory指令,為redis伺服器配置記憶體限制,那麼就可能會有記憶體溢位條件)。 

在呼叫exec命令之後,事務中的某個命令可能會執行失敗。例如,我們對某個鍵執行了錯誤型別的操作(例如,對乙個字串(string)型別的鍵執行列表(list)型別的操作)。

可以使用redis客戶端檢測第一種型別的錯誤,伺服器會記住事務積累命令期間發生的錯誤。然後,redis會拒絕執行這個事務,在執行exec命令之後,便會返回乙個錯誤訊息。最後,redis會自動丟棄這個事務。

相反,在呼叫exec命令之後發生的事務錯誤,redis不會進行任何特殊處理:在事務執行期間,即使某個命令執行失敗,所有其他的命令也將會繼續執行。

在事務執行期間,雖然redis命令可能會執行失敗,但是redis仍然會執行事務中餘下的其他命令,而不會執行回滾操作。

只有當被呼叫的redis命令有語法錯誤時,這條命令才會執行失敗(在將這個命令放入事務佇列期間,redis能夠發現此類問題),或者對某個鍵執行不符合其資料型別的操作:實際上,這就意味著只有程式錯誤才會導致redis命令執行失敗,這種錯誤很有可能在程式開發期間發現,一般很少在生產環境發現。 

redis已經在系統內部進行功能簡化,這樣可以確保更快的執行速度,因為redis不需要事務回滾的能力。

discard命令可以用來中止事務執行。在這種情況下,不會執行事務中的任何命令,並且會將redis連線恢復為正常狀態。示例如下所示:

redis使用watch命令實現事務的「檢查再設定」(cas)行為。

作為watch命令的引數的鍵會受到redis的監控,redis能夠檢測到它們的變化。在執行exec命令之前,如果redis檢測到至少有乙個鍵被修改了,那麼整個事務便會中止執行,然後exec命令會返回乙個null值,提醒使用者事務執行失敗。

例如,設想我們需要將某個鍵的值自動遞增1(假設redis沒有incr命令)。

首次嘗試的偽碼可能如下所示:

val = get mykey

val = val + 1

set mykey $val

如果我們只有乙個redis客戶端在一段指定的時間之內執行上述偽碼的操作,那麼這段偽碼將能夠可靠的工作。如果有多個客戶端大約在同一時間嘗試遞增這個鍵的值,那麼將會產生競爭狀態。例如,客戶端-a和客戶端-b都會讀取這個鍵的舊值(例如:10)。這兩個客戶端都會將這個鍵的值遞增至11,最後使用set命令將這個鍵的新值設定為11。因此,這個鍵的最終值是11,而不是12。

現在,我們可以使用watch命令完美地解決上述的問題,偽碼如下所示:

watch mykey

val = get mykey

val = val + 1

multi

set mykey $val

exec

由上述偽碼可知,如果存在競爭狀態,並且有另乙個客戶端在我們呼叫watch命令和exec命令之間的時間內修改了val變數的結果,那麼事務將會執行失敗。

我們只需要重複執行上述偽碼的操作,希望此次執行不會再出現競爭狀態。這種形式的鎖就被稱為樂觀鎖,它是一種非常強大的鎖。在許多用例中,多個客戶端可能會訪問不同的鍵,因此不太可能發生衝突 —— 也就是說,通常沒有必要重複執行上述偽碼的操作。

Redis事務及訊息發布與訂閱

把一組資料庫運算元據庫的語句放在一起執行,保證操作的原子性。要麼同時成功要麼同時失敗。在redis的事務中,允許把一組redis命令放在一起,把命令序列化,然後一起執行,保證部分原子性。命令 作用multi 用來標記乙個事務的開始,將執行的一組命令放到佇列中。exec 用來執行事務 discard ...

redis事務及鎖應用 發布訂閱模式

mysql和ridis事務對比 redis事務時執行命令放到了佇列裡。注 rollback與discard的區別 如果已經成功執行了2條語句,第三條語句出錯 rollback後前2條語句影響消失。discard只是結束本次事務,前2句造成的影響還在。注 在multi後面的語句中,語句出錯可能有2中情...

Redis訂閱和發布模式和Redis事務

redis訂閱和發布模式 1,概念 redis發布訂閱發布 訂閱 是一種訊息通訊模式 傳送者 酒館 傳送訊息,訂閱者 子 接收訊息。redis的客戶端可以訂閱任意數量的頻道。2,訂閱頻道 訂閱個指定頻道的資訊 3,發布頻道訊息 將資訊訊息傳送到指定的頻道頻道 4,應用場景 2,即使通訊系統 1,學生...