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

歡迎訪問 生活随笔!

生活随笔

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

数据库

Redis 缓存实战——缓存、数据库一致性问题分析与解决方案

發布時間:2025/3/12 数据库 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis 缓存实战——缓存、数据库一致性问题分析与解决方案 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

引言

緩存與數據庫一致性的問題自從出現了緩存概念后就一直被提及,它是一個緩存方案的先天缺陷,只要存在緩存,就勢必會討論緩存與數據庫一致性的問題。

一致性問題還廣泛存在于各種分布式存儲場景中,如主從一致性等等。

本篇博客討論和整理了緩存、數據庫一致性問題的一些思路,在實際的緩存業務場景中,可以對技術實現的起到一定指導作用。

一、為什么會出現一致性問題

緩存作為應用程序與數據庫之間的數據存儲池,主要作用就是熱數據備份的作用,它的主要目的就是提高熱數據的查詢效率。因此,在讀取緩存方面,普遍的做法是沒有疑問的,基本都是按照如下流程執行:

在寫數據方面,卻存在很多問題,其中一點就是——如何保證數據庫的數據與緩存的數據保持一致。

二、強一致性、弱一致性、最終一致性

在一致性問題上,分為事務一致性和數據一致性,而緩存、數據庫一致性很明顯就是數據一致性。

其實只有兩類數據一致性,強一致性和弱一致性。除此之外,所有其他的一致性都是弱一致性的特殊情況。

2.1 強一致性與弱一致性

強一致性又叫線性一致性,顧名思義,就是在多個數據源之間以同步的方式復制數據。

弱一致性,即復制是異步的。在時間中,我們通常使一個從庫是同步的,而其他的則是異步的。如果這個的從庫出現問題,則使另一個異步從庫同步。

這樣可以確保永遠有兩個節點擁有完整數據。主庫和同步從庫,這種配置成為半同步。

2.2 最終一致性

最終一致性表示不一致的狀態可能會出現,但這也只是暫時的,不同的數據源會在未來某個時點保持同步。

而為緩存設置過期時間可以有效的保證最終一致性。

三、緩存更新策略

解決緩存、數據庫一致性問題的方法,無非就是在更新數據庫時盡可能的減少不一致的情況出現。

但只要存在緩存,就無法保證數據的強一致性,選擇不同的緩存更新策略,也只是在弱一致性的前提下,盡可能保證數據的同步,或達到最終一致性。

從理論上來講,共有四種更新策略:

  • 先更新數據庫,再更新緩存
  • 先更新數據庫,再刪除緩存
  • 先更新緩存,再更新數據庫
  • 先刪除緩存,再更新數據庫
  • 一般情況下,為了保證數據的安全,都會第一時間將數據更新到數據庫中,所以先操作緩存的方式往往不被采納。

    對于先更新數據庫的情況,到底是選擇更新緩存還是刪除緩存呢?

    3.1 先更庫,更緩存

    結論是,這種方案普遍不被采納。

    第一點原因,線程安全性,如果同時有請求A 和 請求 B 都要更新數據,那么會出現如下情況:

  • 線程 A 更新了數據庫
  • 線程 B 更新了數據庫
  • 線程 B 更新了緩存
  • 線程 A 更新了緩存
  • 本來按照先后順序,A的更新操作在 B 之前,最終也應該是緩存中存放 B 更新的數據,但是由于一些特殊原因,導致后更新數據的 B 先于 A 更新了緩存,就導致了臟數據。

    第二點原因,如果是一個寫多讀少的場景,采用這種方案由于每次更新數據都要去更新緩存,但從緩存中查詢的次數卻寥寥無幾,不僅沒有起到提高查詢性能的目的,反而還極大的浪費性能。

    3.2 先更庫,刪緩存

    該方案同樣會導致數據不一致。例如,同時有一個請求 A 查詢數據,另一個請求 B 更新數據,會產生如下情形:

  • 緩存剛好失效被清除
  • 請求 A 查詢數據庫,得到一個舊數據
  • 請求 B 將新數據寫入數據庫
  • 請求 B 刪除緩存
  • 請求 A 將查詢到的舊數據寫入緩存
  • 上面的情況是有可能發生的,它產生的原因是由于 A 將取得的舊數據(在 B 更新完數據并執行了刪除緩存操作之后)又放入到了緩存,即緩存中的數據是 A 之前取得的舊數據。

    但是這種情況發生的概率很低,這是因為寫庫操作的速度要遠低于讀庫的速度。正因為如此,請求 B 在將新數據寫入到數據庫后才會大概率在請求 A 將舊數據寫入緩存之后執行刪除緩存操作。

    即大概率發生的情形應該是:

  • 緩存剛好失效被清除
  • 請求 A 查詢數據庫,得到一個舊數據
  • 請求 B 將新數據寫入數據庫
  • 請求 A 將查詢到的舊數據寫入緩存
  • 請求 B 刪除緩存
  • 由于寫庫操作要更加緩慢,因此,大概率會在最后,在其他讀操作的寫入緩存執行后再將緩存刪除,從而保證數據的一致性。

    另外,更新緩存實際上可以看做是先刪除再添加的兩步操作,那么對于刪緩存的操作,無非就是將添加緩存安排到了下次查詢的時候,這也在查詢情況較少的時候避免了頻繁更新緩存的尷尬。

    因此,先更庫,再刪除緩存是一種較為可行的解決一致性問題的方案。

    四、先更庫再刪緩存的其他問題

    如果緩存刪除失敗了怎么辦?

    的確,如果更新了數據庫之后,由于特殊原因,導致緩存刪除失敗,緩存中依然保留了舊數據,那么同樣存在不一致的問題。

    這個時候,我們需要為業務系統增加全局的緩存失效時間,這樣可以保證不一致也只是暫時的,即達到最終一致性的效果。

    或者使用下面的解決方案,使用消息隊列保存數據庫更新后失敗的緩存刪除操作,再某一時點進行重試,其中 binlog 訂閱程序可以選擇現成的MySQL binlog訂閱中間件 “canal”。

    鳴謝:

    《緩存與數據庫的一致性問題解析》

    總結

    以上是生活随笔為你收集整理的Redis 缓存实战——缓存、数据库一致性问题分析与解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。

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