先更新數(shù)據(jù)庫,再刪除緩存
用「讀 + 寫」請求的并發(fā)的場景來分析:
假如某個用戶數(shù)據(jù)在緩存中不存在,請求 A 讀取數(shù)據(jù)時從數(shù)據(jù)庫中查詢到年齡為 20,在未寫入緩存中時另一個請求 B 更新數(shù)據(jù)。它更新數(shù)據(jù)庫中的年齡為 21,并且清空緩存。這時請求 A 把從數(shù)據(jù)庫中讀到的年齡為 20 的數(shù)據(jù)寫入到緩存中。
從上面的理論上分析,先更新數(shù)據(jù)庫,再刪除緩存也是會出現(xiàn)數(shù)據(jù)不一致性的問題,但是在實際中,這個問題出現(xiàn)的概率并不高
因為緩存的寫入通常要遠(yuǎn)遠(yuǎn)快于數(shù)據(jù)庫的寫入
給緩存數(shù)據(jù)加上了「過期時間」,就算在這期間存在緩存數(shù)據(jù)不一致,有過期時間來兜底,這樣也能達(dá)到最終一致
出現(xiàn)的問題:在刪除緩存(第二個操作)的時候失敗了,導(dǎo)致緩存中的數(shù)據(jù)是舊值,而數(shù)據(jù)庫是最新值,導(dǎo)致出現(xiàn)過一段時間才更新生效的現(xiàn)象
如何保證兩個操作都能執(zhí)行成功?
重試機制
用異步操作緩存。
我們可以引入消息隊列,將第二個操作(刪除緩存)要操作的數(shù)據(jù)加入到消息隊列,由消費者來操作數(shù)據(jù)。
如果應(yīng)用刪除緩存失敗,可以從消息隊列中重新讀取數(shù)據(jù),然后再次刪除緩存,這個就是重試機制。當(dāng)然,如果重試超過的一定次數(shù),還是沒有成功,我們就需要向業(yè)務(wù)層發(fā)送報錯信息了。
如果刪除緩存成功,就要把數(shù)據(jù)從消息隊列中移除,避免重復(fù)操作,否則就繼續(xù)重試。
為什么是刪除緩存,而不是更新緩存呢?
刪除一個數(shù)據(jù),相比更新一個數(shù)據(jù)更加輕量級,出問題的概率更小。在實際業(yè)務(wù)中,緩存的數(shù)據(jù)可能不是直接來自數(shù)據(jù)庫表,也許來自多張底層數(shù)據(jù)表的聚合。文章來源:http://www.zghlxwxcb.cn/news/detail-819898.html
比如商品詳情信息,在底層可能會關(guān)聯(lián)商品表、價格表、庫存表等,如果更新了一個價格字段,那么就要更新整個數(shù)據(jù)庫,還要關(guān)聯(lián)的去查詢和匯總各個周邊業(yè)務(wù)系統(tǒng)的數(shù)據(jù),這個操作會非常耗時。 從另外一個角度,不是所有的緩存數(shù)據(jù)都是頻繁訪問的,更新后的緩存可能會長時間不被訪問,所以說,從計算資源和整體性能的考慮,更新的時候刪除緩存,等到下次查詢命中再填充緩存,是一個更好的方案。文章來源地址http://www.zghlxwxcb.cn/news/detail-819898.html
到了這里,關(guān)于Redis---數(shù)據(jù)庫和緩存如何保證一致性?的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!