【緩存一致性】關於數據庫與緩存的一致性問題的分析和解決方案

想起遇到過的緩存與數據庫的問題和一些思考,在這裏做一些系統性的分析和總結,討論一下對數據庫與緩存的一致性問題及解決方案。

1,先更新數據庫再更新緩存

可能出現的問題:

a). A更新數據庫(或發現緩存失效而查詢數據庫)

b). B更新數據庫

c). B更新緩存

d). A更新緩存(覆蓋了B的緩存)

出現數據不一致的問題,且問題發生可能性較小。(如果A更新數據庫較耗時)

另外,當更新數據庫成功但更新緩存失敗時,也會出現緩存髒數據,這時需要等待下一次更新操作來覆蓋髒數據。

解決方案:

a). 當有請求更新數據庫時加讀寫鎖並在緩存中填充佔位符,當最終更新緩存後釋放鎖,保證每次只會有一個請求進行更新操作。(一致性強但有性能影響)

b). 異步延時(令耗時久的操作延時更久)進行更新緩存的操作,投遞到消息中間件儘量保證順序。

2,先更新緩存再更新數據庫

可能出現的問題:

a). A更新緩存(或發現緩存失效而查詢數據庫到應用)

b). B更新緩存

c). B更新數據庫

d). A更新數據庫(或A將a步驟拉取的數據存到緩存)

出現數據不一致的問題,且問題發生可能性較大。(操作緩存的速度很快,所以很難確定c、d操作的順序)

另外,當操作緩存成功但更新數據庫失敗時,也會出現緩存髒數據,這時需要等待下一次更新操作來覆蓋髒數據。

解決方案:

a). 異步延時(令耗時久的操作延時更久)進行更新數據庫的操作,投遞到消息中間件儘量保證順序。

b). 此類問題出現問題的情況比較多且容易,比較難解決,最好的解決方案是不要採用這種方式。

3,先更新數據庫再令緩存失效

可能出現的問題:

a). A發現緩存失效而查詢數據庫

b). B更新數據庫

c). B令緩存失效

d). A將a步驟拉取的數據存到緩存

出現數據不一致的問題,且問題發生的可能性小。(必須滿足的條件是 1.此時剛好緩存失效 2.A,B對同樣的數據操作,存在行級鎖的情況下也會先執行完查詢才能執行更新,而c、d的順序則是由應用層的業務代碼耗時來決定)

另外,當更新數據庫成功但操作緩存失敗時,也會出現緩存髒數據。

解決方案:

a). 異步延時進行緩存失效的操作,根據不同業務場景耗時情況來控制延時時間,可以儘量保證最小時間存在髒數據。

4,先令緩存失效再更新數據庫

可能出現的問題:

a).B令緩存失效

b).A發現緩存失效而查詢數據庫

c).B更新數據庫

d).A將a步驟拉取的數據存到緩存

出現數據庫不一致的問題,且問題發生的可能性較大。(只要d在a操作後時就會出現問題,可能出現的情況太多)

另外,當操作緩存成功但數據庫操作失敗時,令更多的請求打到數據庫上,增加了數據庫壓力。

解決方案:

a). 當有請求更新數據庫時加讀寫鎖並在緩存中填充佔位符,當最終令緩存失效後釋放鎖,保證每次只會有一個請求進行更新操作。(一致性強但有性能影響)

b). 此類問題出現問題的情況比較多且容易,比較難解決,最好的解決方案是不要採用這種方式。

通過分析,得出在數據庫、緩存雙寫儘量保證數據一致性的比較好的選擇應該是先更新數據庫再令緩存失效 。

理由:

1). 出現一致性問題的情況較少且難發生

2). 解決方案較容易實現

另外,對於不同業務上的解決方案也應該有所不同,畢竟不同業務對於數據處理的便利性、性能和數據一致性的要求不同。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章