天天看點

緩存一緻性的問題

随着資料量的不斷提升,資料庫的瓶頸達到最大的巅峰,對于使用者的查詢性能将受到很大的影響,是以引入了緩存,減輕資料庫的壓力,提高通路請求的速度。先讀取緩存資料,緩存中有的話則立即傳回結果,如果沒有,則從資料庫中讀取資料,并且把讀到的資料同步到緩存裡,供下次請求使用。

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

一、分析問題與解決方案

問題的根源其實是讀資料與些資料請求同時并發時候,資料庫與緩存資料已更新,但通路的資料還是老資料,出現了髒讀資料

1、先更新緩存,再更新資料庫

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

2、先更新資料庫,再更新緩存

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

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

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

方案1:讀寫分離

讀請求隻通路緩存,寫請求隻修改資料庫和緩存

緩存一緻性的問題

寫請求修改資料庫和緩存是事務性動作,如果更新資料庫成功,更新緩存失敗,則復原資料庫,保證緩存與資料庫強一緻性,這樣實作了讀寫分離。不僅提高了讀的響應速度,由寫請求負責緩存與資料庫一緻,隻有寫請求成功才會影響到緩存的内容

方案二:隊列存儲請求

緩存一緻性的問題

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

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

繼續閱讀