Redis事務原理

本章主要Redis的事務相關特性

一、與Redis事務相關的基本概念

  • MULTI:用於標記事務的開始,其後執行的命令都將被存入命令隊列,直到執行EXEC時,這些命令纔會被原子執行。
  • EXEC: 執行事務,內部包裝執行了WATCH命令,只有當WATCH所監控的keys沒有被修改的前提下,EXEC命令才能執行事務隊列中的所有命令,否則EXEC將放棄當前事務中的所有命令。(有點相似於CAS)
  • DISCARD:回滾事務隊列中的所有命令,同時再將當前連接的狀態恢復爲正常狀態,即非事務狀態。如 果WATCH命令被使用,該命令將UNWATCH所有的keys。
  • WATCH:在MULTI命令之前,可以指定監控的keys,提供監控(樂觀鎖)的功能,如果key的值發生了變化,就會放棄事務的執行。
  • UNWATCH: 取消當前事務中指定監控的keys,如果執行了EXEC或DISCARD命令,事務中所有的keys都將自動取消WATCH。

二、底層實現

2.1 事務隊列

每個客戶端都有自己的事務狀態,保存在客戶端的mstate屬性中。事務狀態包含一個事務隊列,結構有:

typedef struct redisClient {
    //事務狀態
    multiState mstate;
} redisClient;

type struct multiState {
    //事務隊列,FIFO
    multiCmd *commands;
    //已入隊命令計數器
    int count;
} multiState;

 事務隊列是一個multiCmd類型的數組,數組中每個multiCmd結構都保存了一個已入隊命令的相關信息,包括指向命令實現函數的指針、命令的參數,以及參數數量:

typedef struct multiCmd {
    //參數
    robj **argv;
    //參數數量
    int argc;
    //命令指針
    struct redisCommand *cmd;
} multiCmd;

2.2 執行事務

當客戶端發送exec命令時候,服務器會遍歷客戶端的事務隊列,執行隊列中所有的命令,並把執行結果一次性全部返回給客戶端。

2.3 放棄事務

執行discard命令後,會清空事務隊列,並且客戶端會從事務狀態總退出。

2.4 WATCH的樂觀鎖實現

WATCH 命令可以爲 Redis 事務提供 check-and-set (CAS)行爲。被WATCH的鍵會被監控,如果在 WATCH 執行之後, EXEC 執行之前, 有其他客戶端修改了鍵的值, 那麼當前客戶端的事務就會失敗。

三、Redis事務的理解

事務的ACID特性,在Redis中,需要特別理解:

A:原子性。Redis的原子性是通過事務隊列執行的,EXEC 命令負責觸發並執行事務中的所有命令。當時用AOF持久化時,Redis會使用單個的write命令將事務寫入磁盤中,如果Redis服務因故障只有部分事務寫入磁盤,啓動時重載AOF文件會報錯,使用redis-check-aof程序可以修復這一問題:它會移除 AOF 文件中不完整事務的信息,確保服務器可以順利啓動。

另一方面,如果開啓了事務MULTI,但是未執行EXEC,事務隊列中的命令不會被執行。

C:一致性。在Redis中,一致性不能很好的保證,不支持回滾。

I:隔離性。因爲Redis單線程串行化命令的特點,可以保證事務的隔離性

D:持久性。Redis有RDB和AOF兩種模式做持久化處理。

 

Redis的一致性問題:事務在執行 EXEC 之前,入隊的命令可能會出錯。比如說,命令可能會產生語法錯誤(參數數量錯誤,參數名錯誤,等等),或者其他更嚴重的錯誤,比如內存不足,

  • 在Redis2.6.5之前,客戶端可以根據入隊命令返回QUEUED,判斷是否入隊成功
  • 在Redis2.6.5之後,服務端會對入隊的命令做記錄,如果入隊失敗,執行事務的時候會自動拋棄這些命令

在執行事務的過程中,如果命令出現了錯誤,事務中的其他命令將會繼續執行,對於錯誤的命令,返回結果是nil。

比如

set a 10;
set b lala

multi

incr a
incr b

exec

// 返回結果有:
11
error

從上面的列子中看出,Redis是不支持回滾的。

四、Redis爲什麼不支持回滾

Redis 在事務失敗時不進行回滾,而是繼續執行餘下的命令。主要的原因是:

  • Redis 命令只會因爲錯誤的語法而失敗(並且這些問題不能在入隊時發現),或是命令用在了錯誤類型的鍵上面:這屬於編程錯誤,生產環境中不應該出現。
  • 不支持回滾,可以保持Redis內部簡單快捷

參考文獻:

https://blog.csdn.net/weixin_33704234/article/details/89543128

https://www.jianshu.com/p/ae4c52af3390

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章