Redis事務的分析及改進

2021-07-10 18:07:51 字數 2911 閱讀 5122

資料acid特性滿足了幾條?

為了保持簡單,redis事務保證了其中的一致性和隔離性;

不滿足原子性和永續性;

redis事務在執行的中途遇到錯誤,不會回滾,而是繼續執行後續命令;(違反原子性)

事務可以理解為乙個打包的批量執行指令碼,但批量指令並非原子化的操作;

中間某條指令的失敗不會導致前面已做指令的回滾,也不會造成後續的指令不做;

比如:

redis 

127.0

.0.1

:7000

>

multi

okredis

127.0

.0.1

:7000

>

seta aaa

queued

redis

127.0

.0.1

:7000

>

setb bbb

queued

redis

127.0

.0.1

:7000

>

setc ccc

queued

redis

127.0

.0.1

:7000

>

exec1)

ok2)ok

3)ok

如果在set b bbb處失敗,set a已成功不會回滾,set c還會繼續執行;

事務不過是用佇列包裹起了一組 redis 命令,並沒有提供任何額外的永續性功能,所以事務的永續性由 redis 所使用的持久化模式決定:

redis事務在執行的過程中,不會處理其它命令,而是等所有命令都執行完後,再處理其它命令(滿足隔離性)

redis事務在執行過程中發生錯誤或程序被終結,都能保證資料的一致性;(詳見參考資料1)

除了不保證原子性和永續性,在實際使用中還有以下問題:

1) 遇到有查詢的情況穿插在事務中間,不會返回結果;

設定事務開始標誌後,所有的命令都是queued,即使是查詢指令;

如果後續的更新操作需要依賴於前面的查詢指令,那redis事務就無法有效的完成任務;

例如:

redis 

127.0

.0.1

:7000

>

multi

okredis

127.0

.0.1

:7000

>

seta aaa

queued

redis

127.0

.0.1

:7000

>

getb

queued

業務邏輯...

redis

127.0

.0.1

:7000

>

setc ccc

queued

redis

127.0

.0.1

:7000

>

exec1)

ok2)bbb3)

ok

第二步 get a 返回的是queued,並不是a的查詢結果,

如果後續的set操作依賴於get的結果(存在依賴業務邏輯),就不能將get操作放在事務操作中;

2) 事務中的每條命令都與redis伺服器進行了一次網路互動;

redis 事務指定開始後,執行乙個事務返回的都是queued,那這個入隊操作是在客戶端實現,還是在伺服器端實現的?

檢視原始碼,很容易發現是在伺服器端實現;

在redis.c中有這麼一段:

int

processcommand

(redisclient *c

)else

return

redis_ok

;}

這裡就涉及到客戶端與伺服器端的多次互動,明明是需要一次批量執行的n條命令,還需要通過多次網路互動,有些浪費;

如果有這樣的需求:在事務開始後,中間穿插有查詢邏輯;

那麼使用redis事務(單庫),無法滿足這個要求;

可能的解決方案:

可以考慮使用多個庫,讀寫分離,查詢庫只用來查詢,更新庫用來開事務做寫操作;

不再使用redis的事務指令,自己在客戶端將待執行的命令批量打包,決定是否回滾還是全部執行;這樣可以在更新的間隙執行查詢邏輯;而不需要將查詢邏輯提前到事務指令multi之前;

將查詢業務邏輯提前;嚴格規範**編寫要求,所有的redis查詢邏輯都放在事務之外:

redis 

127.0

.0.1

:7000

>

getb

bbb業務邏輯...

redis

127.0

.0.1

:7000

>

multi

ok redis

127.0

.0.1

:7000

>

seta aaa

queued

redis

127.0

.0.1

:7000

>

setc ccc

queued

redis

127.0

.0.1

:7000

>

exec1)

ok 2)

ok

將多個命令打包批量傳送到redis伺服器執行,減少網路互動,優化效能,可能的解決方案:

對於所有的get/set操作,可使用現有的mget/mset指令;

對於各種不同型別的更新操作,可使用lua指令碼將命令打包後,傳送到伺服器端一次執行;

Redis事務的分析及改進

資料acid特性滿足了幾條?為了保持簡單,redis事務保證了其中的一致性和隔離性 不滿足原子性和永續性 redis事務在執行的中途遇到錯誤,不會回滾,而是繼續執行後續命令 違反原子性 事務可以理解為乙個打包的批量執行指令碼,但批量指令並非原子化的操作 中間某條指令的失敗不會導致前面已做指令的回滾,...

Redis事務原理分析

在redis的事務裡面,採用的是樂觀鎖,主要是為了提高效能,減少客戶端的等待。由幾個命令構成 watch,unwatch,multi,exec,discard。通過watch,可以實現cas操作。使用watch監聽一些鍵,然後去檢查鍵的值,然後根據鍵的值來決定是否還需要進行multi,如果鍵的值被改...

Redis的事務分析與簡介

事務 redis 事務可以一次執行多個命令,並且帶有以下兩個重要的保證 事務是乙個單獨的隔離操作 事務中的所有命令都會序列化 按順序地執行。事務在執行的過程中,不會被其他客戶端傳送來的命令請求所打斷。事務是乙個原子操作 事務中的命令要麼全部被執行,要麼全部都不執行。乙個事務從開始到執行會經歷以下三個...