天天看點

資料庫緩存一緻性如何保證?

作者:程式設計少年

1.緩存的使用流程

資料庫緩存一緻性如何保證?

目前從理論上來講,給緩存設定過期時間,是保證最終一緻性的解決方案。這種方案下,我們可以對存入緩存的資料設定過期時間,所有的寫操作以資料庫為準,對緩存操作隻是盡最大努力即可。也就是說如果資料庫寫成功,緩存更新失敗,那麼隻要到達過期時間,則後面的讀請求自然會從資料庫中讀取新值然後回填緩存。目前讨論的不依賴于給緩存設定時間這個方案。

2. 三種更新政策比較

資料庫緩存一緻性如何保證?

2.1 先更新資料庫,後更新緩存

資料庫緩存一緻性如何保證?

如圖所示,同時請求A和請求B進行更新操作:

1.線程A更新了資料庫

2.線程B更新了資料庫

3.線程B更新了緩存

4.線程A更新了緩存

這就出現請求A更新緩存應該比請求B更新緩存早才對,但是因為網絡等原因,B 卻比A更早更新了緩存,這樣就導緻了髒資料。

總結:先更新資料庫,再更新緩存,這套方案容易出現髒資料。

2.1 先删除緩存,再更新資料庫

資料庫緩存一緻性如何保證?

如圖所示,同時有一個請求A進行更新操作,有一個請求B進行查詢操作,那麼就會出現上圖執行的場景:

1.線程A删除緩存。

2.線程B查詢緩存資料。

3.線程B發現緩存資料不存在,查詢資料庫資料。

4.線程B将查詢的舊值寫入緩存。

5.線程A将新值更新至資料庫

這就出現了緩存和資料庫不一緻的現象,出現髒資料的場景。

總結:先删除緩存,再更新資料庫,這套方案容易出現髒資料。

2.3 先更新資料庫,後删除緩存

資料庫緩存一緻性如何保證?

如果發生上述情況,确實是會發生髒資料,但是發生上述情況有一個先天性條件,那就是步驟(3)的寫資料庫操作比步驟(2)的讀資料庫操作耗時更短,才有可能使得步驟(4)先于步驟(5),可是,大家想想,資料庫的讀操作的速度遠快于寫操作的(不然做讀寫分離幹嘛,做讀寫分離的意義就是因為讀操作比較快,耗資源少,是以步驟(3)耗時比步驟(2)更短,這一情形很難出現,,如實非要解決這種情況,那麼可以采用給緩存設有效時間或者采用延時删除緩存的的政策,保證請求完成後再進行删除操作。

可是這邊還存在一個小的隐患,那就是如果步驟(4)删除緩存失敗,還是會出現髒資料,那應該如何解決呢?

資料庫緩存一緻性如何保證?

總結:先更新資料庫,後删除緩存,遇到緩存删除失敗時,結合對删除失敗事件進行消息補償重試完成資料的一緻性,推薦使用這種方案