讀請求
先讀快取再讀庫
如果快取命中,返回資料
如果快取未命中,讀庫並把資料寫入快取,然後再返回
寫請求
資料寫庫
刪除快取
這裡很重要的一點在寫請求中,要刪除快取而不是更新快取。快取的更新會發生在下一次讀請求時。這裡為什麼會選擇刪除快取,而沒有更新快取呢。因為如果更新快取的話,存在併發寫操作時,無法保證多個程序的執行順序,有可能舊資料會覆蓋新資料。 cache aside pattern方案雖然使用範圍比較廣,但它本身也存在一些問題。
問題一
如上圖,程序a在t1時刻資料寫入庫中,t2時刻刪除了快取。在高併發場景下,t1和t2時刻之間的讀請求從快取中讀到的資料和庫中的資料會出現不一致。
問題二
如上圖,程序a在t1時刻把資料寫入庫中,t2時刻刪除快取失敗。失敗的原因暫不詳談。這種情況下會導致庫和快取資料長時間不一致。
問題三
如上圖,程序a是讀請求,程序b是寫請求。
程序a讀快取未命中,然後從庫中讀到值a;
此時程序a可能因為某種原因發生了程序切換。
程序b執行寫庫,把值b寫入庫中;
程序b刪除快取。
程序a排隊完成繼續執行,把值a寫入快取。
此時庫中資料是b,快取中是a,出現了資料不一致。
方案二是在方案一的基礎上發展而來的。
讀請求
同方案一
寫請求
刪除快取
資料寫庫,返回寫入成功
睡眠一段時間(通常是幾百ms、也可以是一定時間範圍內的隨機值,根據具體業務場景決定)
刪除快取
此方案的寫請求,與cache aside pattern方法相比,最前面多了一次刪除快取,這樣就可以避免t1~t2時間差的資料不一致。在最後刪除快取前有乙個短暫的等待,這樣就避免了方案一中的問題三:防止因為上下文切換等原因導致的資料不一致問題。
讀請求
先讀快取再讀庫
如果快取命中,返回資料
如果快取未命中,取鎖(可重試多次)
取鎖成功,讀庫並把資料寫入快取
釋放鎖
寫請求
取鎖取鎖成功後,資料寫庫
刪除快取
釋放鎖加鎖之後,資料一致效能得到很好的保證,但是資料的訪問效率會受到較大的影響。所以,很多時候加鎖未必是理想方案。不過在寫少、讀多的業務場景中也可以考慮。
讀請求
先讀快取再讀庫
如果快取命中,返回資料
如果快取未命中,讀庫並把資料寫入快取,然後再返回
寫請求
只寫資料庫
對於快取的更新,我們採用訂閱資料庫日誌的方式實現。比如採用阿里開源的canal,訂閱mysql的binlog,然後放入mq,消費端消費資料,然後把資料和快取中的資料進行比較,把不一致的資料從快取中刪除。刪除失敗可以嘗試多次刪除。這種方案,可以把快取刪除邏輯從業務**中剝離,業務開發專注於業務;但是需要引入額外的元件,花費更高的維護成本。
以上是處理庫和快取資料一致性問題的常用方案。他們都有乙個共同點刪除快取,而不是更新快取。不管是哪一種方案,都很難做到庫和快取資料完全一致。所以在各方案中,都可以加非同步的對賬邏輯,定期檢查庫和快取中的資料是否一致,出現不一致時,刪除快取資料即可。
資料一致性
資料一致性通常指關聯資料之間的邏輯關係是否正確和完整。而資料儲存的一致性模型則可以認為是儲存系統和資料使用者之間的一種約定。如果使用者遵循這種約定,則可以得到系統所承諾的訪問結果。常用的一致性模型有 a 嚴格一致性 linearizability,strict atomic consistency ...
資料一致性
丟失更新 未確定的相關性 不一致的分析和幻想讀 事務a讀取與搜尋條件相匹配的若干行。事務b以插入或刪除行等方式來修改事務a的結果集,然後再提交。幻讀是指當事務不是獨立執行時發生的一種現象,例如第乙個事務對乙個表中的資料進行了修改,比如這種修改涉及到表中的 全部資料行 同時,第二個事務也修改這個表中的...
資料一致性
資料一致性通常指關聯資料之間的邏輯關係是否正確和完整。而資料儲存的一致性模型則可以認為是儲存系統和資料使用者之間的一種約定。如果使用者遵循這種約定,則可以得到系統所承諾的訪問結果。常用的一致性模型有 a 嚴格一致性 linearizability,strict atomic consistency ...