Redis更新快取同步資料庫的理解

2021-08-28 11:40:28 字數 940 閱讀 4529

問題:當資料庫有資料更新時,怎樣保證redis快取中的資料與資料庫資料一致?

redis更新的正確方法

原文(快取更新的套路):看到好些人在寫更新快取資料**時,先刪除快取,然後再更新資料庫,而後續的操作會把資料再裝載的快取中。然而,這個是邏輯是錯誤的。試想,兩個併發操作,乙個是更新操作,另乙個是查詢操作,更新操作刪除快取後,查詢操作沒有命中快取,先把老資料讀出來後放到快取中,然後更新操作更新了資料庫。於是,在快取中的資料還是老的資料,導致快取中的資料是髒的,而且還一直這樣髒下去了。

檢視分析:

寫流程(更新策略)

先淘汰 cache(刪除快取);

再寫 db(更新資料庫)。

讀流程先讀 cache,如果資料命中 hit 則返回;

如果資料未命中 miss 則讀 db;

將 db 中讀取出來的資料入快取。

什麼情況下可能出現快取和資料庫不一致呢?

在分布式環境下,資料的讀寫都是併發的,上游有多個應用,通過乙個服務的多個部署(為了保證可用性,一定是部署多份的),對同乙個資料進行讀寫,在資料庫層面併發的讀寫並不能保證完成順序,也就是說後發出的讀請求很可能先完成(讀出髒資料):

發生了寫請求 a,a 的第一步淘汰了 cache(如上圖中的1);

a 的第二步寫資料庫,發出修改請求(如上圖中的2);

發生了讀請求 b,b 的第一步讀取 cache,發現 cache 中是空的(如上圖中的步驟3);

b 的第二步讀取資料庫,發出讀取請求,此時 a 的第二步寫資料還沒開始,讀出了乙個髒資料放入 cache(如上圖中的步驟4)。

最終導致快取與資料庫不一致。

先更新資料庫,後刪除快取(建議,使用場景最多),但是,是不是這個就不會有併發問題了?不是的,比如,乙個是讀操作,但是沒有命中快取,然後就到資料庫中取資料,此時來了乙個寫操作,寫完資料庫後,讓快取失效,然後,之前的那個讀操作再把老的資料放進去,所以,會造成髒資料。

redis快取如何同步資料庫

redis快取如何同步資料庫 redis mysql模式 讀 服務程式先從快取中讀取資料,如果命中,則將資料讀出。如果未命中,則在資料庫中讀取資料,然後將資料寫入到快取中去。更新資料 常見的模式是先到資料庫中寫入,然後刪除快取中的資料。產生的不一致 讀 只是讀資料一般不會有不一致出現。更新 1 資料...

redis快取和mysql資料庫同步

穿透 頻繁查詢乙個不存在的資料,由於快取不命中,每次都要查詢持久層。從而失去快取的意義。解決辦法 持久層查詢不到就快取空結果,查詢時先判斷快取中是否exists key 如果有直接返回空,沒有則查詢後返回,注意insert時需清除查詢的key,否則即便db中有值也查詢不到 當然也可以設定空快取的過期...

redis資料庫快取

使用redis作為快取,資料還需要存入資料庫中嗎?我的答案是 1redis只是快取,不是資料庫如mysql,所以redis中有的資料庫,mysql中一定有。2使用者請求先去請求redis,如果沒有,再去資料庫中去讀取。3redis中快取一些請求量比較大的資料 這些快取資料,mysql中一定也是有的 ...