Redis與資料庫一致性問題解決方案

2021-10-25 20:19:40 字數 1096 閱讀 3527

1、先刪快取,再更新資料庫

該方案會導致不一致的原因是。同時有乙個請求a進行更新操作,另乙個請求b進行查詢操作。那麼會出現如下情形:

(1)請求a進行寫操作,刪除快取

(2)請求b查詢發現快取不存在

(3)請求b去資料庫查詢得到舊值

(4)請求b將舊值寫入快取

(5)請求a將新值寫入資料庫

上述情況就會導致不一致的情形出現。而且,如果不採用給快取設定過期時間策略,該資料永遠都是髒資料。

那麼,如何解決呢?採用延時雙刪策略

偽**如下

public void write(string key,object data)
轉化為中文描述就是

(1)先淘汰快取

(2)再寫資料庫(這兩步和原來一樣)

(3)休眠1秒,再次淘汰快取

這麼做,可以將1秒內所造成的快取髒資料,再次刪除。

那麼,這個1秒怎麼確定的,具體該休眠多久呢?

針對上面的情形,讀者應該自行評估自己的專案的讀資料業務邏輯的耗時。然後寫資料的休眠時間則在讀資料業務邏輯的耗時基礎上,加幾百ms即可。這麼做的目的,就是確保讀請求結束,寫請求可以刪除讀請求造成的快取髒資料。

2、先更新資料庫,再刪快取

這種情況不存在併發問題麼?

不是的。假設這會有兩個請求,乙個請求a做查詢操作,乙個請求b做更新操作,那麼會有如下情形產生

(1)快取剛好失效

(2)請求a查詢資料庫,得乙個舊值

(3)請求b將新值寫入資料庫

(4)請求b刪除快取

(5)請求a將查到的舊值寫入快取

ok,如果發生上述情況,確實是會發生髒資料。

然而,發生這種情況的概率又有多少呢?

發生上述情況有乙個先天性條件,就是步驟(3)的寫資料庫操作比步驟(2)的讀資料庫操作耗時更短,才有可能使得步驟(4)先於步驟(5)。可是,大家想想,資料庫的讀操作的速度遠快於寫操作的(不然做讀寫分離幹嘛,做讀寫分離的意義就是因為讀操作比較快,耗資源少),因此步驟(3)耗時比步驟(2)更短,這一情形很難出現。

redis快取與資料庫一致性問題

不一致產生的原因 我們在使用redis過程中,通常會這樣做 先讀取快取,如果快取不存在,則讀取資料庫。偽 如下 object stuobj new object public stu getstufromcache string key return stu 寫資料庫的偽 如下 public voi...

快取與資料庫一致性問題

業務場景 抓拍到的人臉需要推送到第三方系統,但不是所有的網點都需要推送資訊。也就是要做到不同的網點可以根據配置來決定是否推送,前端頁面需要有推送配置功能,手動配置後,把配置的推送資訊儲存到資料庫。抓拍到人臉 後,讀取配置的推送資訊,再判斷是否需要推送。由於網點多抓拍的人臉資料量較大,推送資訊配置後不...

Redis和資料庫的一致性問題

問題背景 在高併發場景下,更新快取中和資料和更新資料庫中的資料,都會存在併發性問題。情況 1 刪除了redis的某條資料,還沒來得及刪除資料庫中的資料 此時乙個執行緒來讀,發現redis中沒有這條資料,它就從資料庫中讀取出的尚未刪除的資料,重新寫回redis中,造成redis刪除失效且髒資料 2 如...