緩存一致性的問題

隨着數據量的不斷提升,數據庫的瓶頸達到最大的巔峯,對於用戶的查詢性能將受到很大的影響,因此引入了緩存,減輕數據庫的壓力,提高訪問請求的速度。先讀取緩存數據,緩存中有的話則立即返回結果,如果沒有,則從數據庫中讀取數據,並且把讀到的數據同步到緩存裏,供下次請求使用。

雖說這樣減輕了數據庫的壓力,但在多線程高併發的場景下,可能會導致緩存和數據庫不一致的問題,這需要我們解決!!!

一、分析問題與解決方案

問題的根源其實是讀數據與些數據請求同時併發時候,數據庫與緩存數據已更新,但訪問的數據還是老數據,出現了髒讀數據

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

方案不行,原因是更新緩存成功嗎,更新數據庫出現了異常,導致緩存與數據庫完全不一致

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

同樣也不行,數據庫更新成功了,但緩存更新失敗,同樣會出現數據不一致的問題

合理的方案是再遇到寫請求的時候,可以先刪除緩存數據,再更新數據庫,這樣不管數據庫更新失敗還是緩存刪除失敗,緩存與數據庫始終一致,這種方案滿足上萬人的併發

雖說上述可以,但遇到一些極端的上億的併發情況,上述顯然不行,比方說雙十一,A用戶搶購該商品,數量減少,消費者A搶購成功,這時應該刪除緩存,更新數據庫商品數量,但再更新商品數量之前,又有一個消費者B來查看商品數量。因爲緩存爲空,則到數據庫中查詢,發現商品數量沒變,還是原來一樣,從而導致緩存與數據庫不一致的問題

方案1:讀寫分離

讀請求只訪問緩存,寫請求只修改數據庫和緩存

寫請求修改數據庫和緩存是事務性動作,如果更新數據庫成功,更新緩存失敗,則回滾數據庫,保證緩存與數據庫強一致性,這樣實現了讀寫分離。不僅提高了讀的響應速度,由寫請求負責緩存與數據庫一致,只有寫請求成功纔會影響到緩存的內容

方案二:隊列存儲請求

沿用場景一的解決方案,爲解決其缺陷,添加隊列,凡是遇到寫請求,則將寫請求放入隊列中,由隊列對寫請求統一管理,寫請求處理成功,則從隊列中刪除。當有一個讀請求過來時,到隊列查詢,是否有對應的寫請求,如果有則放入隊列中,等待寫請求執行完之後再執行讀請求。爲防止某個請求阻塞情況,爲其設置超時機制或者過期機制。

這種方案雖可行,但是倘若訪問量大,處理器來不及處理,隊列內的請求數量越來越高,則會影響查詢效率。出現這種情況,就要加機器集羣執行,幫忙分擔壓力

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