如何保證快取與資料庫資料一致性

2021-09-24 22:06:22 字數 1415 閱讀 5044

重點文章:

你只要用快取,就可能會涉及到快取與資料庫雙儲存雙寫,你只要是雙寫,就一定會有資料一致性的問題,那麼你如何解決一致性問題?

一般來說,就是如果你的系統不是嚴格要求快取+資料庫必須一致性的話,快取可以稍微的跟資料庫偶爾有不一致的情況,最好不要做這個方案,讀請求和寫請求序列化,串到乙個記憶體佇列裡去,這樣就可以保證一定不會出現不一致的情況

序列化之後,就會導致系統的吞吐量會大幅度的降低,用比正常情況下多幾倍的機器去支撐線上的乙個請求。

將不一致分為三種情況:

資料庫有資料,快取沒有資料;

資料庫有資料,快取也有資料,資料不相等;

資料庫沒有資料,快取有資料。

在討論這三種情況之前,先說明一下使用快取的策略,叫做 cache aside pattern。簡而言之就是

1. 首先嘗試從快取讀取,讀到資料則直接返回;如果讀不到,就讀資料庫,並將資料會寫到快取,並返回。

2. 需要更新資料時,先更新資料庫,然後把快取裡對應的資料失效掉(刪掉)。

第一種資料庫有資料,快取沒有資料:在讀資料的時候,會自動把資料庫的資料寫到快取,因此不一致自動消除.

第二種資料庫有資料,快取也有資料,資料不相等:資料最終變成了不相等,但他們之前在某乙個時間點一定是相等的(不管你使用懶載入還是預載入的方式,在快取載入的那一刻,它一定和資料庫一致)。這種不一致,一定是由於你更新資料所引發的。前面我們講了更新資料的策略,先更新資料庫,然後刪除快取。因此,不一致的原因,一定是資料庫更新了,但是刪除快取失敗了。

第三種資料庫沒有資料,快取有資料,情況和第二種類似,你把資料庫的資料刪了,但是刪除快取的時候失敗了。

因此,最終的結論是,需要解決的不一致,產生的原因是更新資料庫成功,但是刪除快取失敗。

解決方案大概有以下幾種:

對刪除快取進行重試,資料的一致性要求越高,我越是重試得快。

定期全量更新,簡單地說,就是我定期把快取全部清掉,然後再全量載入。

給所有的快取乙個失效期。

第三種方案可以說是乙個大殺器,任何不一致,都可以靠失效期解決,失效期越短,資料一致性越高。但是失效期越短,查資料庫就會越頻繁。因此失效期應該根據業務來定。

併發不高的情況:

讀: 讀redis->沒有,讀mysql->把mysql資料寫回redis,有的話直接從redis中取;

寫: 寫mysql->成功,再寫redis;

併發高的情況:

讀: 讀redis->沒有,讀mysql->把mysql資料寫回redis,有的話直接從redis中取;

寫:非同步話,先寫入redis的快取,就直接返回;定期或特定動作將資料儲存到mysql,可以做到多次更新,一次儲存;

快取與資料庫資料一致性

1 無論是雙寫模式還是失效模式,都會導致快取的不一致問題。即多個例項同時更新會出事。怎麼辦?解決方案 a 如果是使用者緯度資料 訂單資料 使用者資料 這種併發機率非常小,不用考慮這個問題,快取資料加上過期時間,每隔一段時間觸發讀的主動更新即可 b 如果是選單,商品介紹等基礎資料,也可以去使用cana...

資料庫 快取資料一致性

1 不推薦更新快取 建議刪除快取 2 採用延時雙刪 先刪快取,後更新資料庫,延時再刪一次快取 但是會存在問題 改庫後延時時間內的資料可能是舊資料 如果業務場景要求,改庫成功就不能使用舊資料,可以採用如下優化方案 新增乙個快取型別,記錄key是否被更新過,並且設定自動過期時間 在訪問的時候,先查詢ke...

資料庫快取如何保證一致性

先新資料庫再更新快取。問題 更新資料庫後,更新快取時,如果資料庫資料又變更了,那快取裡就更新成髒資料了。先刪除快取,然後再更新資料庫。刪除快取後,進行更新資料庫時,如果乙個請求來了,它在快取中沒命中,就會去資料庫中查詢,並把查到的資料更新到快取裡,隨後資料庫才更新完畢,這就導致快取裡的資料又成為髒資...