Redis事務原理分析

2022-05-05 02:42:09 字數 2084 閱讀 7228

在redis的事務裡面,採用的是樂觀鎖,主要是為了提高效能,減少客戶端的等待。由幾個命令構成:watch, unwatch, multi, exec, discard。

通過watch,可以實現cas操作。使用watch監聽一些鍵,然後去檢查鍵的值,然後根據鍵的值來決定是否還需要進行multi,如果鍵的值被改了,則重新。(因為有可能在執行watch前,鍵的值被改了,所以需要先watch,然後再作判斷)。在執行multi命令後,如果中途watch的鍵的值被修改了,後續再執行exec時,整個事務都會被終止。

cas使用示例:

假設存在乙個string型別的狀態值,state,需要對其進行cas操作:

watch state

value = get state;

if value == 1

unwatch state

return false;

multi

set state 1

result = exec

if result == success

return true;

return false;

通過上述的基本應用可以知道,redis是通過watch命令,來保證當前事務的資料是否被修改過,如果被修改了,則整個事務會中止,不再執行。那麼,redis在實現的時候,會儲存對應的watch key,然後中途如果該key被修改了,則會將對應的所有客戶端的標誌位都置為client_dirty_cas,表示資料被修改,後續執行exec的時候則會被中斷,從而實現事務。而unwatch命令則是從儲存的watch_keys裡面移除。multi命令僅僅將客戶端的標誌位flags置為client_multi,表示處於multi狀態,該狀態下,後續的命令(除了multi/watch/discard/exec)外,其它命令都會被儲存到乙個列表裡面,直到exec或者discard命令執行。如果中途出現了語法錯誤之類的命令,則會將flags置為client_dirty_exec。後續執行exec時,如果flags存在client_dirty_cas或者client_dirty_exec,則整個事務會被中止,不執行任何命令。

針對redis的事務實現,對於acid,個人認為,對於atomicity和durability以及consistency,redis是不滿足的。為什麼會對acid進行分析呢,一部分原因是為了作對比學習,另一部分是因為《redis設計與實現》19章事務acid性質裡面提到了一些觀點,個人不太認同,所以進行了一些對比。

atomicity

指的是要麼不執行,要麼全部執行。當其中一部分執行了,但是另外一部分沒有執行,那麼作為整個事務,是全部要回滾,都不執行的,而redis在執行過程中,如果出現操作和型別不一致,則會導致一部分執行,而一部分錯誤的情況,即不滿足原子性。當然,除去部分失誤外,還是能夠保證原子性的,但是這並不是嚴格的原子性要求。

durability

永續性,事務提交後,無論出現任何情況,包括系統斷電之類的,重啟後都是可以恢復的。對於redis來說,即使開啟了aof以及設定為always,也存在命令執行一部分後,系統宕機而導致資料不一致的情況,不能恢復。一般都是通過write-ahead-logging來實現的,即事先寫日誌,而redis是邊執行邊寫日誌。

consistency

一致性,指從乙個有效的狀態轉到另乙個有效的狀態,不滿足上述的兩個條件,也無法儲存一致性,即會出現中間狀態。比如從乙個人的賬戶轉到另外乙個人上面,執行了轉出,但是沒有執行轉入的時候宕機了,就會導致資料的不一致。

isolation

隔離性,在多個事務併發的情況下,事務之間不會被影響。對於redis來說,事務的執行是序列的,中途不會插入其它命令的執行,所以是滿足隔離性的。

watch監聽key,首先就要有地方儲存監聽的key,redis針對不同的客戶端,會在客戶端的結構體裡面維護乙個watch監聽key的列表,以及在server裡面維護乙個全域性的雜湊表,key為被監聽的key,value則為乙個鍊錶,裡面儲存了所有監聽該key的客戶端。如下圖:

當執行watch account時,則首先會判斷該key是否已在客戶端裡面,如果存在,則直接返回,否則加入到客戶端對應的watched_keys列表裡面,然後再將其加入到對應db的watched_keys字典表裡面,key為 account,value則為該客戶端。

Redis事務命令與原理

開始事務 multi在執行 multi 命令後,後面執行的非事務相關的命令都會被加入事務佇列,等待事務執行 執行事務 exec執行 multi 和 exec 之間的命令,並統一返回 監視鍵watch key key 監視乙個或多個鍵,如果監視的鍵的值發生了改變,那麼事務將不被執行,並且返回 nil。...

Redis集群原理分析

redis集群的原理主要是圍繞著 槽 的概念展開的,先來理解集群中 槽 的概念。reids集群是通過將所有的key進行分割槽來實現的,redis集群最多有16384個分割槽 也可以稱作 槽 英文 slot 然後在集群節點中指定分割槽範圍來實現。例如 集群中的節點a負責0 10000,節點b負責 10...

Redis原始碼分析之事務

redis是通過multi discard exec watch四個命令來實現事務的。事務提供了一種將多個命令打包,然後一次性並順序的執行所有命令的機制,並且事務在執行中不會主動中斷,伺服器只有在事務執行完後,才會繼續執行其他客戶端的請求。下面是乙個事務的例子 redis multi okredis...