天天看點

redis 多條指令 一次操作_Redis管道-釋出訂閱-事務

管道(pipeline)

redis執行一次指令包括下面幾個流程:

1、用戶端發送指令(經過網絡傳輸)。

2、服務端執行指令-。

3、服務端響應結果(經過網絡傳輸)。

redis 多條指令 一次操作_Redis管道-釋出訂閱-事務

如上圖,Redis每一次指令的發送都要經過發送指令請求、執行指令、響應結果,而這個過程中所消耗的時間大部分都是在網絡傳輸上,是以如果能減少網絡傳輸的次數,也就意味着性能也會大幅度提高。

redis 多條指令 一次操作_Redis管道-釋出訂閱-事務

沿着這個思路是以就有了管道的概念,管道可以在我們批量操作一些指令的時候,不需要每個指令都依次的去進行發送、執行、響應的流程,而是把多個指令一次性發送給服務端,在服務端執行完成後,把結果統一響應給用戶端,最終以達到減少網絡請求進而提升了整體的效率。

redis 多條指令 一次操作_Redis管道-釋出訂閱-事務

使用管道技術可以顯著提升Redis處理指令的速度,其原理就是将多條指令打包,隻需要一次網絡開銷,在伺服器端和用戶端隻需要一次請求和響應,以此來節約時間。

釋出訂閱

Redis裡也提供了釋出訂閱的機制,如果一個消息想要被多個人收到,或者發消息的人不知道會有哪些人需要收到這些消息,那麼Redis的釋出訂閱功能就可以解決這個問題。釋出訂閱模式是通過建立一個頻道,然後消息發送者統一把對應的消息發送到這個頻道裡,然後頻道可以支援多個訂閱者進行消息訂閱,訂閱了該頻道的訂閱者都會收到發送者的消息。

redis 多條指令 一次操作_Redis管道-釋出訂閱-事務

在Redis用戶端可通過subscribe 和 publish指令可以分别實作消息訂閱和消息推送的功能,如下面,左邊的用戶端通過subscribe訂閱了一個頻道為 test的頻道,然後右邊的頻道通過publish往test頻道發送一條消息後,左邊訂閱了該頻道的用戶端就會收到消息。

redis 多條指令 一次操作_Redis管道-釋出訂閱-事務

Redis實作釋出|訂閱的原理

簡單的說Redis是通過一個字典(pubsub_channels)和一個連結清單實作釋出訂閱功能的。 字典記錄着Redis裡面所建立的頻道,然後每個頻道有一個對應的連結清單記錄着訂閱了該頻道的用戶端。當執行publish channel message 指令時,首先會找到對應channel的頻道,然後找到該頻道對應的連結清單資料,通過周遊連結清單中的用戶端逐一的把消息發送出去。

redis 多條指令 一次操作_Redis管道-釋出訂閱-事務

需要注意的是Redis實作的釋出訂閱模式并不能保證消息的可靠性,這主要展現在兩個方面,一是用戶端隻有線上的情況下才會收到訂閱消息,因為Redis并不會像專業的消息隊列一樣把消息進行持久化儲存的。另外一個方面是何網絡系統在執行操作時都可能會遇到斷網的情況,而斷線産生的連接配接錯誤通常會使得網絡連接配接兩端中的一端進行重新連接配接。如果用戶端在執行訂閱操作的過程中斷線,那麼用戶端将會丢失在斷線期間的消息。是以如果業務對于消息可靠性沒有這種高的要求,那麼是可以嘗試Redis的釋出訂閱功能。

事務

Redis裡也提供了事務機制,在Redis裡可以通過如下方式開啟和執行一個事務。

1、開啟事務:
multi
           
2、發送多個指令到事務隊列中
set  t1   1
 set  t2   2
 set  t3   3
           
3、執行或取消事務
exec
 discard
           

Redis開始事務後,後面的發出的指令并不會馬上執行,而是會放入到一個隊列裡,直到輸入事務指令(exec或者discard)指令才會決定對事務隊列的指令進行執行或者取消。

redis 多條指令 一次操作_Redis管道-釋出訂閱-事務

事務中斷機制(watch)

如果我們在執行事務的過程中涉及到的資料有可能會被其他地方修改,那麼這個時候就有可能出現資料髒讀的問題。為了解決髒讀的問題,Redis提供了watch機制,watch就是事先對可能出現髒讀的key進行監控,執行事務的過程中如果有其它地方對監控的key進行了資料變更,那麼watch會将對應的key進行标記,那麼最終在執行事務的時候會根據watch裡對應key的标記來決定是否最終執行指令。

如果在用戶端1執行的事務的過程中,用戶端2對用戶端1監控的key進行修改,那麼最後事務會取消執行,整個過程如下圖:

redis 多條指令 一次操作_Redis管道-釋出訂閱-事務

Redis事務與傳統的ACID

從上面我們了解的事務來看,Redis裡的事務并非我們常識裡帶有ACID特性的事務,相比于傳統的ACID事務,Redis裡的事務缺少事務的復原機制,并沒有辦法實作事務的一緻性、原子性。

原子性:

Redis的事務中能保證指令執行的原子性,整體事務的指令要麼全部執行,要麼全部不執行。

一緻性:

在Redis的事務中,如果某個指令執行失敗,那麼後面的指令依然會執行,Redis并沒有傳統事務的復原機制,是以在指令錯誤的情況下,是無法保證資料的一緻性。

隔離性:

Redis是串行化執行事務的,多個事務同時開啟時,事務的執行順序,是以最終送出事務的順序執行,是以Redis事務之間天然就具備隔離性。

持久性:

Redis的事務持久性由設定的持久化模式決定,隻有在AOF持久化模式下并且appendfsync選項的值為always時,這時指令都将同步寫入AOF檔案中,此時事務具備持久性的。如果在AOF異步同步指令模式下,又或者在RDB模式下都有可能丢失指令資料,這種場景中Redis事務是不具備持久性的。