應用中引入快取層後,快取和持久化層資料一致性的思考

2021-10-11 01:27:19 字數 1992 閱讀 8527

乙個應用中決定加快取(redis,memcached)之前,要考慮的第乙個問題就是,引進了快取之後,會帶來哪些收益(利),付出哪些代價,引起哪些額外的問題(弊)?

任何新的中介軟體引進,收益和成本都是伴隨的,只有當利大於弊的情況下,能夠容忍其弊端(徹底解決?沒有額外代價又沒有負面影響,是不可能的,那就是不用就行了),才值得引進。

以redis作為快取為例,引進之後,其利和弊也是伴隨的。

帶來的收益:加速讀寫,提高併發性,降低後端持久化層資料庫的負載

付出的代價:增加**複雜,快取本身的運維,潛在的資料不一致造成的影響。

資料不一致的存在

引進redis(或者其他快取)之後,應用程式和資料持久化層多了乙個中間層,部分資料儲存由原來的單一持久化層,變為快取層和持久化層兩份。

這兩部分資料在相互同步的過程中,在某些時間點上的維度來看,可能會潛在不一致的情況。

其中,潛在的資料不一致,是任何乙個引進快取層之後最面臨的最大的乙個問題(當然兩者最終的資料是要保持一致的,這一點是底線)。

首先需要衡量的就是,這種潛在的不一致,會引發什麼樣的問題,帶來的問題是否可以接受範圍之內,或者是否會對應用程式邏輯引起致命的問題。

快取和持久化層儲存可能會不一致,往往是快取和持久化層未同步重新整理引起的,

具體舉例說明:

第一種情況,比如點讚次數,瀏覽次數等等(讀多寫少的場景,寫mysql,讀redis,寫入了資料庫但是尚未同步到快取層這個間隙)。

不會對業務產生嚴重的邏輯錯誤,這種暫時性的資料不一致是可以忍受的,另外就是,通過重新整理等手段,兩者資料最終會達成一致。

第二種情況,比如銀行卡取款取超,導致餘額為負數,快取和持久化層儲存的不一致造成嚴重的邏輯錯誤,這種是無法忍受的。

就需要考慮這種快取層本身的設計是否合理?

輕量級做法,**邏輯實現

如果對於快取的合理性沒有問題,且業務邏輯上要求快取和持久化層強一致,那麼久要實現資料庫的一致性操作。

對於快取和持久化層資料的一致性實現,個人的話,思路有以下兩種,

輕量級的做法如下:

對於引起資料變化的邏輯,一般都是「寫操作」,比如對資料的update或者delete,

1,首先去delete快取中對應的資料(而不是去對應的update、delete,為什麼?因為只要delete成功,快取被清理之後,就消除了不一致的可能性,或者併發造成的資料覆蓋錯誤(update),而非update就做不到),如果執行成功,再去操作持久化層的資料庫。

2,對於insert操作,保證寫持久化庫成功,非同步寫快取(而不用刻意關注是否寫成功)。

重量級分布式鎖實現,雙寫實現強一致

雙寫的安全性一般要通過分布式鎖來實現,分布式鎖可以通過zookeeper或者redis實現。

一旦考慮使用分布式鎖,又要考慮分布式鎖的載體的安全性,也即不管是用zookeeper或者redis,要考慮zookeeper或者redis的安全性(集群)。

這樣下去,問題會變得非常複雜,純粹變為解決問題-->引入新的問題-->解決問題的死迴圈。

如果要保持一致,當然雙寫也是一種選擇,不過通過雙寫來確保資料的絕對一致,不但會對整體效率產生負面的影響,實現也是比較困難的,暫時不討論這種方案。

如果是分布式鎖,任何寫入性操作,比如update,delete等,如下:

1,直接鎖定相關key值

2,依次操作快取層和持久化層,同時做好每一層的回滾操作,一旦任何一步失敗,都要回滾

3,最終不管成功或者失敗,都釋放key

分布式鎖這種方式的話,實現起來,原**中業務侵入性較多,比較複雜

重量級佇列化請求

如果是使用佇列,將可能導致不一致性的訪問,佇列化執行,其實這種方式,也是比分布式鎖更加重量級的,基本上會顛覆原始的邏輯實現,一般很少採用。

但是不管怎麼樣,快取層和持久化層,最終的資料是要保持一致的,這一點是底線。

整體來看,引不引入快取層,是從整體效能、業務邏輯、實現代價、資料一致性的容忍程度等多個方面決定的。

持久化資料 快取資料雙寫一致性

快取中資料更新一般有兩個入口,快取未過期,資料庫資料有變動主動更新至快取 關於資料一致性 需要將髒資料的存在時間範圍放在可控範圍內 併發 因為無事務,無法保證雙寫的一致性 多資料來源 如果拿著乙份資料分別向持久層和快取執行執行更新,在時序無法保證時會出現交叉覆蓋的情況 互斥 快取的初始化 查詢資料 ...

redis快取和mysql資料一致性方案詳解

在高併發的業務場景下,資料庫訪問成為使用者併發最薄弱的環節,所以就需要redis做乙個緩衝操作,讓請求先訪問到redis,而不是直接訪問mysql資料庫 讀取redis快取一般沒有什麼問題,但是一旦涉及到資料更新,更新資料庫和redis快取,就容易出現快取redis和資料庫mysql間的資料一致性問...

redis資料一致性,開發中關於快取和資料同步問題

在開發中出現很多關於快取和資料共存問題,本小g網上翻閱cache aside pattern 一些資料,加上專案體驗寫下 寫下這一小簡,大家一塊來 使用場景 在使用redis來做資料快取,減輕資料壓力和速度,但是有乙個問題就是快取和mysql資料如何資料一致 一般開發設計為 重點內容 查詢流程 如果...