您的位置:  首頁 > 技術 > 中間件 > 正文

Mysql和Redis數據如何保持一致

2022-08-23 18:00 https://my.oschina.net/u/4090830/blog/5568797 京東云開發者 次閱讀 條評論

先闡明一下Mysql和Redis的關系:Mysql是數據庫,用來持久化數據,一定程度上保證數據的可靠性;Redis是用來當緩存,用來提升數據訪問的性能。

關于如何保證Mysql和Redis中的數據一致(即緩存一致性問題),這是一個非常經典的問題。

使用過緩存的人都應該知道,在實際應用場景中,要想實時刻保證緩存和數據庫中的數據一樣,很難做到。

基本上都是盡可能讓他們的數據在絕大部分時間內保持一致,并保證最終是一致的。

緩存不一致是如何產生的

如果數據一直沒有變更,那么就不會出現緩存不一致的問題。

通常緩存不一致是發生在數據有變更的時候。 因為每次數據變更你需要同時操作數據庫和緩存,而他們又屬于不同的系統,無法做到同時操作成功或失敗,總會有一個時間差。在并發讀寫的時候可能就會出現緩存不一致的問題(理論上通過分布式事務可以保證這一點,不過實際上基本上很少有人這么做)。

雖然沒辦法在數據有變更時,保證緩存和數據庫強一致,但對緩存的更新還是有一定設計方法的,遵循這些設計方法,能夠讓這個不一致的影響時間和影響范圍最小化。

緩存更新的幾種設計

緩存更新的設計方法大概有以下四種:

  • 先刪除緩存,再更新數據庫(這種方法在并發下最容易出現長時間的臟數據,不可取)

  • 先更新數據庫,刪除緩存(Cache Aside Pattern)

  • 只更新緩存,由緩存自己同步更新數據庫(Read/Write Through Pattern)

  • 只更新緩存,由緩存自己異步更新數據庫(Write Behind Cache Pattern)

接下來詳細介紹一些這四種設計方法

先刪除緩存,再更新數據庫

這種方法在并發讀寫的情況下容易出現緩存不一致的問題

?

如上圖所示,其可能的執行流程順序為:

  • 客戶端1 觸發更新數據A的邏輯

  • 客戶端2 觸發查詢數據A的邏輯

  • 客戶端1 刪除緩存中數據A

  • 客戶端2 查詢緩存中數據A,未命中

  • 客戶端2 從數據庫查詢數據A,并更新到緩存中

  • 客戶端1 更新數據庫中數據A

可見,最后緩存中的數據A跟數據庫中的數據A是不一致的,緩存中的數據A是舊的臟數據。

因此一般不建議使用這種方式。

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

這種方法在并發讀寫的情況下,也可能會出現短暫緩存不一致的問題

?

如上圖所示,其可能執行的流程順序為:

  • 客戶端1 觸發更新數據A的邏輯

  • 客戶端2 觸發查詢數據A的邏輯

  • 客戶端3 觸發查詢數據A的邏輯

  • 客戶端1 更新數據庫中數據A

  • 客戶端2 查詢緩存中數據A,命中返回(舊數據)

  • 客戶端1 讓緩存中數據A失效

  • 客戶端3 查詢緩存中數據A,未命中

  • 客戶端3 查詢數據庫中數據A,并更新到緩存中

可見,最后緩存中的數據A和數據庫中的數據A是一致的,理論上可能會出現一小段時間數據不一致,不過這種概率也比較低,大部分的業務也不會有太大的問題。

只更新緩存,由緩存自己同步更新數據庫(Read/Write Through Pattern)

這種方法相當于是業務只更新緩存,再由緩存去同步更新數據庫。 一個Write Through的 例子如下:

?

?

如上圖所示,其可能執行的流程順序為:

  • 客戶端1 觸發更新數據A的邏輯

  • 客戶端2 觸發查詢數據A的邏輯

  • 客戶端1 更新緩存中數據A,緩存同步更新數據庫中數據A,再返回結果

  • 客戶端2 查詢緩存中數據A,命中返回

Read Through 和 WriteThrough 的流程類似,只是在客戶端查詢數據A時,如果緩存中數據A失效了(過期或被驅逐淘汰),則緩存會同步去數據庫中查詢數據A,并緩存起來,再返回給客戶端

這種方式緩存不一致的概率極低,只不過需要對緩存進行專門的改造。

只更新緩存,由緩存自己異步更新數據庫(Write Behind Cache Pattern)

這種方式性詳單于是業務只操作更新緩存,再由緩存異步去更新數據庫,例如:

?

?

如上圖所示,其可能的執行流程順序為:

  • 客戶端1 觸發更新數據A的邏輯

  • 客戶端2 觸發查詢數據A的邏輯

  • 客戶端1 更新緩存中的數據A,返回

  • 客戶端2 查詢緩存中的數據A,命中返回

  • 緩存異步更新數據A到數據庫中

這種方式的優勢是讀寫的性能都非常好,基本上只要操作完內存后就返回給客戶端了,但是其是非強一致性,存在丟失數據的情況。

如果在緩存異步將數據更新到數據庫中時,緩存服務掛了,此時未更新到數據庫中的數據就丟失了。

總結

上面講到的幾種緩存更新的設計方式,都是前人總結出來的經驗,這些方式或多或少都有一些弊端,并不完美,實際上也很難有完美的設計。 大家在做系統設計的時候,也不要去追求完美,要有一些取舍,找到一種最適合自己業務場景的方式就行

作者:追光者

展開閱讀全文
  • 0
    感動
  • 0
    路過
  • 0
    高興
  • 0
    難過
  • 0
    搞笑
  • 0
    無聊
  • 0
    憤怒
  • 0
    同情
熱度排行
友情鏈接
18禁高潮出水呻吟娇喘mp3,日本熟妇乱人伦A片免费高清,成人午夜精品无码区,狠狠色噜噜色狠狠狠综合久久,麻豆一区二区99久久久久,年轻的妈妈4,少妇被又大又粗又爽毛片,护士张开腿让我爽了一夜,男男互攻互受h啪肉np文,你好神枪手电视剧免费观看啊,97人妻一区二区精品免费,久久久婷婷五月亚洲97号色,freegaysexvideos男男中国,国产精品国产三级国av麻豆,国产精品又黄又爽又色无遮挡网站,亚洲av无码一区二区三区网站,亚洲国产精品久久久久蜜桃,国产真人无码作爱视频免费,国产成人精品亚洲一区二区三区,亚洲欧洲日产最新,老司机带带我精彩免费,国产成人久久精品激情,日本最新av免费一区二区三区,边摸边吃奶又黄又激烈视频
<蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>