日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

【经典问题】mysql和redis数据一致性问题

發布時間:2024/1/5 数据库 32 coder
生活随笔 收集整理的這篇文章主要介紹了 【经典问题】mysql和redis数据一致性问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

MySQL和Redis數據一致性算是個很經典的問題,在之前也看到過很多相關的文章,最近心血來潮,想把一致性問題的解決方案和存在問題都總結一下。

不推薦方案

1 先更新MySQL,再更新Redis。

如上圖有兩個請求要同時進行更新操作,在并發情況下,B請求雖然更新時間晚于A請求,但是可能因為網絡延遲問題,導致本來A請求要先更新Redis的操作晚于B請求更新Redis的操作,最終導致了MySQL出現數據不一致。

2 先更新Redis,在更新MySQL。

這種情況其實等同于第一種情況。

3 先刪除Redis緩存,再更新MySQL。

A請求對數據的更新操作晚于請求B的讀取操作,導致B請求將數據庫的舊值又寫回緩存,刪除緩存在這種情況下沒有意義。

推薦方案

1 先刪除Redis緩存,再更新MySQL,再刪一次Redis緩存(延遲雙刪)

在第三種情況中,出現了刪除緩存后被其他請求更新為舊值的情況,那么在這種情況下,再刪除一遍緩存不就可以解決問題了。這里第二次刪除緩存的時間必須在B請求回寫舊值之后,所以要社招好第二次刪除緩存的等待時間,根據業務實際耗時來定,假設B請求回寫緩存要300ms,那么A請求可以設置等待500ms再進行緩存刪除。

但是上面這種情況也會出現問題,比如延遲雙刪的時候刪除緩存失敗怎么辦。

這個時候可以借助MQ重試機制。如下圖:

將刪除的請求放到MQ隊列里面,然后系統再從MQ里面取出刪除請求的操作,由于MQ支持失敗重試,刪除失敗后會繼續投遞消息。

2 先更新MySQL,再刪除Redis緩存。

在上面這種情況下,請求B出現了讀取了一次舊值,如果對于業務是一致性要求沒那么強的話(比如秒殺,減庫存),這種方案也是可以的,誤差范圍是可以接收的,只存在這么一次數值是舊的情況。

當然還有特殊情況如下:

當B請求先查詢Redis,這個時候redis剛好緩存失效,B請求就會去MySQL查詢舊值,后續B請求回寫舊值的請求又晚于A請求刪除緩存的請求,導致緩存里面放的是舊值。

但是這種情況出現需要 同時滿足以下兩個條件:

(1)緩存剛好失效

(2)讀請求回寫緩存的時間晚于寫請求回寫緩存的時間

上述兩個條件同時成立的概率是極小的,綜上來說,這種方案還是不錯的,復雜度也不高,但同時也是可能存在刪除緩存失敗的特殊情況導致誤差。

3 先更新MySQL,通過 Binlog,異步更新 Redis

A請求更新完MySQL,借助Canal進行監聽并把相關的修改記錄推送到MQ,MQ經過消費系統拉取消息對Redis進行更新,如果在Redis更新之前,有新的讀請求,依然會導致數據不一致性的問題,但是這種方案能夠實現最終一致性。

在這里Canal作為一個組件,監聽binlog和發送消息到MQ都由Canal完成。

方案總結

前三種方案都是不推薦使用的。對于推薦使用的方案,從實時性和技術復雜度來說,先寫數據庫再刪除緩存是比較好的選擇。如果要確保最終一致性的話,可以用binlog異步更新緩存的方案。

總結

以上是生活随笔為你收集整理的【经典问题】mysql和redis数据一致性问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。