引言:關於 Redis 的事務很多人可能都是一知半解,大多數人只了解資料庫的事務,並且是單體事務,對於 Redis 事務和常見關系型資料庫的事務的區別還沒有去了解過,本文就來詳細進行介紹。
題目
Redis的事務與關系型資料庫事務有何不同?
更多題目請見
推薦解析
原子性差異
關系型資料庫(比如 MySQL):事務中的所有操作要麽全部完成,要麽全部不完成,具有強原子性。Redis:在 4.0 之前的版本中,事務實際上是透過 MULTI/EXEC 命令來實作的一系列命令的批次執行,如果中途某個命令失敗,後續命令仍會執行。從 Redis 4.0 開始,引入了事務的原子性保證,但這種保證僅在客戶端使用 MULTI/EXEC 時有效。
永續性差異
推薦去看下 MySQL 刷盤機制和 Redis 的刷盤機制,關於系統呼叫、後台執行緒、數據恢復等問題。
關系型資料庫:事務完成後,更改的數據會被持久化到磁盤,即使系統崩潰也不會遺失。Redis:作為一個記憶體資料庫,數據主要儲存在記憶體中。雖然 Redis 透過 RDB 和 AOF 機制提供了數據的持久化,但事務操作的永續性取決於配置和具體的持久化策略。
隔離性差異
關系型資料庫:通常提供嚴格的隔離級別,如讀已送出(Read Committed)、可重復讀(Repeatable Read)和序列化(Serializable)。Redis:單執行緒模型天然避免了並行導致的數據不一致問題,但 Redis 的事務沒有隔離級別的概念,事務中的命令在執行前不會被其他客戶端觀察到,但執行過程中可能會與其他客戶端的命令交錯執行。
一致性差異
關系型資料庫:在事務開始和結束時,資料庫從一個一致的狀態轉移到另一個一致的狀態。Redis:事務保證了操作的原子性,但對一致性的支持取決於具體的操作和數據結構。
並行控制
關系型資料庫:使用鎖或其他並行控制機制來處理多個事務的並行執行。Redis:由於單執行緒模型,Redis 自身不會在伺服器端進行並行控制,但客戶端庫可能實作樂觀鎖或事務的其他並行控制機制。
事務範圍
關系型資料庫:事務可以跨越多個表和資料庫物件。Redis:事務通常局限於單個 Redis 連線和單個資料庫例項。
單體事務 VS 分布式事務
單體事務通常指在一個單一的資料庫管理系統(DBMS)內部執行的事務。這種事務涉及的操作都是針對同一個資料庫例項。
分布式事務涉及多個資料庫或服務,它們可能分布在不同的伺服器、套用或地理位置上。
分布式事務比單體事務更復雜,涉及到網路通訊、多個系統間的協調等。
分布式事務解決方案
關於分布式可以去了解下 CAP 理論和 BASE 理論,對分布式理解還是很有幫助的。
兩階段送出協定(2PC) 這是一種經典的分布式事務解決方案,透過準備階段和送出階段來確保所有參與者要麽全部送出,要麽全部回滾。
三階段送出協定(3PC) 這是對2PC的改進,增加了超時機制,以解決協調者故障時參與者的阻塞問題。
補償事務(TCC) TCC 代表 Try、Confirm 和 Cancel 三個操作。在 Try 階段進行資源檢測和預留,在 Confirm 階段送出業務操作,在 Cancel 階段釋放預留資源。
訊息佇列 + 事件驅動 利用訊息佇列來保證本地操作和發送訊息的原子性,透過事件驅動架構來處理訊息,實作最終一致性。
使用 Seata Seata 是一個開源的分布式事務解決方案,支持 AT、TCC、Saga 和 XA 等事務模式,透過全域事務協調者和分支事務的協調來處理分布式事務。
其他補充
魚聰明 AI 的回答:
魚聰明 AI 地址:https://www.yucongming.com/
隨著Redis版本的升級,其架構從最初的單執行緒逐步引入了多執行緒特性,以提高效能和擴充套件性。以下是Redis單執行緒和多執行緒的升級歷程,以及分布式鎖的實作方法:
Redis單執行緒到多執行緒的升級
Redis 4.0之前 :
Redis主要采用單執行緒模型,所有的命令執行和網路通訊都在一個主執行緒中順序執行。
Redis 4.0及之後 :
雖然Redis仍然主要在單個主執行緒中執行命令,但引入了後台執行緒處理一些耗時操作,如異步持久化、過期鍵的清理等。
Redis 6.0 :
引入了多執行緒特性,但主要用於處理網路IO的讀寫操作,而非命令執行。這意味著Redis仍然保持了單執行緒執行命令的原子性和一致性,同時利用多核CPU提高了網路IO的效能。
Redis多執行緒的實作
IO多執行緒 :Redis 6.0透過配置檔啟用IO多執行緒,可以設定多個IO執行緒來處理網路請求的讀寫操作。
執行緒數設定 :建議的執行緒數通常小於CPU核心數,以避免執行緒上下文切換的開銷。
命令執行 :即使啟用了多執行緒,Redis的命令執行仍然在主執行緒中順序執行,保持了操作的原子性。
分布式鎖的實作
分布式鎖是分布式系統中用於同步不同行程或服務對共享資源存取的機制。以下是實作Redis分布式鎖的一些常見方法:
SETNX + EXPIRE :
使用
SETNX
命令嘗試設定鍵,若成功則使用
EXPIRE
設定鍵的過期時間。
SET命令擴充套件 :
使用
SET
命令的
NX
(Not Exist)和
EX
(秒級過期)或
PX
(毫秒級過期)選項原子性地設定鍵和過期時間。
Lua指令碼 :
透過Lua指令碼保證
SETNX
和
EXPIRE
的原子性執行,減少因命令分開執行導致的競態條件。
Redlock演算法 :
一種高級的分布式鎖演算法,透過嘗試在多個獨立的Redis例項上加鎖來提高鎖的安全性。
Redisson框架 :
Redisson是一個基於Redis的Java客戶端庫,提供了多種分布式鎖的實作,包括Redlock演算法和自動續期機制。
多機分布式鎖 :
在多Redis例項部署的情況下,使用如Redisson提供的Redlock實作,確保分布式鎖的高可用性和安全性。
其他實作 :
包括使用Redisson的
RLock
物件或其他高級API來簡化分布式鎖的獲取和釋放操作。
分布式鎖的最佳實踐
鎖的粒度 :盡量使用細粒度的鎖,以減少鎖爭用。
鎖的超時 :合理設定鎖的超時時間,避免死結。
鎖的重入 :支持鎖的重入性,允許同一執行緒多次獲取同一把鎖。
鎖的安全性 :確保鎖只能被持有者釋放,防止其他執行緒誤操作。
透過上述方法,Redis不僅可以透過多執行緒提升效能,還可以作為分布式系統中實作同步機制的關鍵元件。隨著Redis版本的不斷升級,其在分布式系統中的套用也越來越廣泛。
歡迎交流
本文主要介紹 Redis 事務和常規的關系型資料庫事務的不同之處,另外還有講解單體事務和分布式事務的區別以及分布式事務的主要解決方案,關於程式碼實踐部份需要讀者自己去進行了解,因為一個案例並不能解決實際問題,需要不同場景進行對應的分析,在文末還有三個問題,歡迎小夥伴在評論區進行留言,面試鴨小程式已經全面上線,想要刷題備戰實習拿 offer 的同學可以搜尋面試鴨小程式!
1)Redis事務的原子性是如何在4.0版本之後得到改進的,相比於關系型資料庫的事務原子性,它有哪些限制或不同之處?
2)在Redis 6.0引入多執行緒特性後,對於事務的處理方式有沒有變化?如果有,這些變化對事務的執行和效能有哪些影響?
3)在實作分布式鎖時,Redis的Redlock演算法是如何確保在多個Redis例項之間保持鎖的安全性的,它相比其他分布式鎖實作方式有哪些優勢和潛在的風險?
點燃求職熱情!每周持續更新,海量面試題和大廠面經等你挑戰!趕緊關註面試鴨公眾號,輕松備戰春招和暑期實習!
往期推薦