Redis怎麼保持快取與資料庫一致性?

2021-08-25 22:05:33 字數 1864 閱讀 8414

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

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

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

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

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

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

讀的邏輯大家都很容易理解,談談更新。如果不採取我提到的這種更新方法,你還能想到什麼更新方法呢?大概會是:先刪除快取,然後再更新資料庫。這麼做引發的問題是,如果a,b兩個執行緒同時要更新資料,並且a,b已經都做完了刪除快取這一步,接下來,a先更新了資料庫,c執行緒讀取資料,由於快取沒有,則查資料庫,並把a更新的資料,寫入了快取,最後b更新資料庫。那麼快取和資料庫的值就不一致了。另外有人會問,如果採用你提到的方法,為什麼最後是把快取的資料刪掉,而不是把更新的資料寫到快取裡。這麼做引發的問題是,如果a,b兩個執行緒同時做資料更新,a先更新了資料庫,b後更新資料庫,則此時資料庫裡存的是b的資料。而更新快取的時候,是b先更新了快取,而a後更新了快取,則快取裡是a的資料。這樣快取和資料庫的資料也不一致。按照我提到的這種更新快取的策略,理論上也是有不一致的風險的,之前在其他的部落格文章有看到過,只不過概率很小,我們暫時可以不考慮,後面我們有其他手段來補救。討論完使用快取的策略,我們再來看這三種不一致的情況。

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

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

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

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

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

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

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

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

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

併發不高的情況:

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

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

併發高的情況:

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

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

redis資料庫快取

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

資料庫 如何保持Redis和MySQL資料一致

原文 redis在啟動之後,從資料庫載入資料。讀請求 不要求強一致性的讀請求,走redis,要求強一致性的直接從mysql讀取 寫請求 資料首先都寫到資料庫,之後更新redis 先寫redis再寫mysql,如果寫入失敗事務回滾會造成redis中存在髒資料 mysql處理實時性資料,例如金融資料 交...

Python程式設計 redis快取資料庫

broker快取 mongodb 存硬碟 redis 預設存記憶體,配置可存硬碟 memcache 只能存記憶體 remote dictionary server redis redis官網 redis資料型別 string 操作 set get hash 操作 hset hget list 操作 ...