最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

保證緩存和數(shù)據(jù)庫的數(shù)據(jù)一致性詳解

 更新時間:2023年04月13日 09:10:40   作者:愛吃糖的靚仔  
在實際開發(fā)過程中,緩存的使用頻率是非常高的,只要使用緩存和數(shù)據(jù)庫存儲,就難免會出現(xiàn)雙寫時數(shù)據(jù)一致性的問題,本文主要介紹了如何保證緩存和數(shù)據(jù)庫的數(shù)據(jù)一致性,需要的小伙伴可以參考閱讀

1、錯誤的解決方案

1.1、 先更新數(shù)據(jù)庫,再刪除緩存

若數(shù)據(jù)庫更新成功,刪除緩存操作失敗,則此后讀到的都是緩存中過期的數(shù)據(jù),造成不一致問題。

1.2、 先更新數(shù)據(jù)庫,再更新緩存

同刪除緩存策略一樣,若數(shù)據(jù)庫更新成功緩存更新失敗則會造成數(shù)據(jù)不一致問題。

1.3、 先刪除緩存,再更新數(shù)據(jù)庫

1.4、 先更新緩存,再更新數(shù)據(jù)庫

若緩存更新成功數(shù)據(jù)庫更新失敗, 則此后讀到的都是未持久化的數(shù)據(jù)。因為緩存中的數(shù)據(jù)是易失的,這種狀態(tài)非常危險。

2、正確的解決方案

2.1、使用 CAS

CAS (Check-And-Set 或 Compare-And-Swap)是一種常見的保證并發(fā)安全的手段。CAS 當且僅當客戶端最后一次取值后該 key 沒有被其他客戶端修改的情況下,才允許當前客戶端將新值寫入。

func CAS(oldVal, newVal) {
    if cache.get() == oldVal {
        cache.set(newVal)
    }
}

  • 目前一些兼容 Redis 協(xié)議的中間件已經(jīng)提供了 CAS 命令的支持,比如阿里的 Tair 以及騰訊的 Tendis。
  • Redis 官方本身是不支持CAS的操作,但是我們可以通過WATCH 和MULTI 命令實現(xiàn)類似的效果
  • WATCH 命令用于監(jiān)視一個或多個鍵的變化,并在某個鍵被修改后取消事務,從而確保事務的原子性
  • MULTI 命令用于開始一個事務,將多個命令打包成一個事務,然后一次性執(zhí)行。如果在執(zhí)行事務期間有其他客戶端對事務中的鍵進行修改,那么事務會被取消

2.2、使用分布式鎖

CAS 假設發(fā)生并發(fā)問題的概率不大, 所以 CAS 也被稱為樂觀鎖。那么悲觀鎖能否解決我們的問題呢?

還是以「先更新數(shù)據(jù)庫,再更新緩存」方案中兩個寫線程競爭為例, 我們要求任何線程在寫入或讀取數(shù)據(jù)庫前都需要獲取排它鎖。

分布式鎖同樣可以解決并發(fā)問題,只是成本可能略高。

2.3、使用消息隊列異步更新

使用消息隊列實現(xiàn)異步更新時,可以將緩存更新的請求發(fā)送到消息隊列中,由消息隊列異步地處理緩存更新操作。下面是一個簡單的案例:

假設有一個電商網(wǎng)站,需要對商品信息進行緩存。當用戶訪問商品詳情頁面時,先從緩存中讀取商品信息,如果緩存中沒有,則從數(shù)據(jù)庫中讀取。

  • 當商品信息發(fā)生變化時,需要更新緩存中的數(shù)據(jù)。這時可以通過消息隊列異步更新緩存,具體步驟如下:
  • 當商品信息發(fā)生變化時,先更新數(shù)據(jù)庫中的數(shù)據(jù)。
  • 將商品信息更新請求發(fā)送到消息隊列中。
  • 消息隊列異步地處理緩存更新操作,讀取最新的商品信息,并將其更新到緩存中。

這樣就可以保證緩存中的數(shù)據(jù)是最新的,避免了因為緩存中的數(shù)據(jù)過期而導致的數(shù)據(jù)不一致問題。同時,使用消息隊列可以提高更新的可靠性和性能,避免因為緩存更新失敗而導致的數(shù)據(jù)庫和緩存數(shù)據(jù)不一致問題。

為什么異步更新可以解決

  • 異步更新緩存:當商品信息發(fā)生變化時,先更新數(shù)據(jù)庫中的數(shù)據(jù),然后將緩存更新請求發(fā)送到消息隊列中,由消息隊列異步地處理緩存更新操作。這樣,即使緩存更新失敗,也不會影響數(shù)據(jù)庫中的數(shù)據(jù),僅僅是緩存中的數(shù)據(jù)不是最新的而已。
  • 消息隊列的可靠性:消息隊列通常具有高可靠性和高可用性,可以保證消息的可靠傳輸和處理。即使在消息隊列出現(xiàn)故障的情況下,也可以通過消息隊列的備份、重試等機制來保證消息的可靠性。因此,即使緩存更新失敗,也可以通過重試等機制來保證緩存最終被更新。

如果通過異步更新,更新緩存還是失敗了怎么辦

  • 重試更新緩存:當緩存更新失敗時,可以嘗試重新更新緩存。可以設置重試次數(shù)和重試間隔時間,避免因為頻繁重試而影響性能。
  • 回滾數(shù)據(jù)庫更新:當緩存更新失敗時,可以回滾數(shù)據(jù)庫中的更新操作,保證數(shù)據(jù)庫和緩存中的數(shù)據(jù)一致。但是,回滾操作可能會影響數(shù)據(jù)庫中的其他操作,需要考慮到這個問題。
  • 延遲更新緩存:當緩存更新失敗時,可以將緩存更新請求放入一個延遲隊列中,一段時間后再次嘗試更新緩存。這樣可以避免頻繁重試而影響性能,同時保證緩存最終被更新。
  • 使用讀寫分離:將讀請求和寫請求分別處理,讀請求從緩存中讀取數(shù)據(jù),寫請求先更新數(shù)據(jù)庫,再更新緩存。這樣可以避免因為緩存更新失敗而導致的數(shù)據(jù)不一致問題。

2.4、將數(shù)據(jù)庫更新和緩存更新放在同一個事務中

可以保證在事務執(zhí)行成功時,數(shù)據(jù)庫和緩存中的數(shù)據(jù)都被更新;在事務執(zhí)行失敗時,數(shù)據(jù)庫和緩存中的數(shù)據(jù)都不會被更新,保證了數(shù)據(jù)的一致性。

  • 要將MySQL和Redis放入同一個事務中,需要使用分布式事務處理框架,如XA或TCC。這些框架可以確保在整個事務過程中,MySQL和Redis的操作都能夠得到正確的協(xié)調(diào)和同步。
  • XA:XA是一種分布式事務處理標準,它可以確保在多個數(shù)據(jù)庫之間進行事務處理時,所有的操作都能夠得到正確的協(xié)調(diào)和同步。在MySQL和Redis中都有XA實現(xiàn),可以通過XA接口實現(xiàn)分布式事務。
  • TCC:TCC是一種補償性事務處理框架,它通過預留資源、確認資源和釋放資源三個步驟來實現(xiàn)分布式事務。在MySQL和Redis中都有TCC實現(xiàn),可以通過TCC接口實現(xiàn)分布式事務。
  • 需要注意的是,使用分布式事務框架會增加系統(tǒng)的復雜性和開銷,需要仔細考慮是否真正需要在MySQL和Redis之間實現(xiàn)分布式事務如果可以接受稍微降低一些數(shù)據(jù)一致性的風險,可以使用其他技術(shù)來實現(xiàn)MySQL和Redis之間的數(shù)據(jù)同步,如消息隊列、定時任務等。

到此這篇關(guān)于保證緩存和數(shù)據(jù)庫的數(shù)據(jù)一致性詳解的文章就介紹到這了,更多相關(guān)緩存和數(shù)據(jù)庫數(shù)據(jù)一致性內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實現(xiàn)公用實體類轉(zhuǎn)Tree結(jié)構(gòu)

    Java實現(xiàn)公用實體類轉(zhuǎn)Tree結(jié)構(gòu)

    這篇文章主要為大家介紹了一個Java工具類,可以實現(xiàn)Java公用實體類轉(zhuǎn)Tree結(jié)構(gòu),文中的示例代碼簡潔易懂,感興趣的小伙伴可以參考一下
    2024-10-10
  • Spring中ImportBeanDefinitionRegistrar源碼和使用方式

    Spring中ImportBeanDefinitionRegistrar源碼和使用方式

    Spring容器擴展流程總結(jié):1. 定義Mapper層,2. 通過FactoryBean創(chuàng)建代理對象,3. 使用ImportBeanDefinitionRegistrar修改Bean定義,4. 應用自定義注解@LuoyanImportBeanDefinitionRegistrar,5. 配置類中執(zhí)行后置處理器,6. 啟動類中查看源碼,希望對大家有所幫助
    2024-11-11
  • java實現(xiàn)國產(chǎn)sm4加密算法

    java實現(xiàn)國產(chǎn)sm4加密算法

    這篇文章主要介紹了java實現(xiàn)國產(chǎn)sm4加密算法的步驟,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-12-12
  • LibrarySystem圖書管理系統(tǒng)開發(fā)(一)

    LibrarySystem圖書管理系統(tǒng)開發(fā)(一)

    這篇文章主要為大家詳細介紹了LibrarySystem圖書管理系統(tǒng)開發(fā),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • Java中的synchronized關(guān)鍵字

    Java中的synchronized關(guān)鍵字

    這篇文章主要介紹了Java中的synchronized關(guān)鍵字,synchronized可以保證方法或代碼塊在運行時,同一時刻只有一個線程可以進入到臨界區(qū)(互斥性),同時它還保證了共享變量的內(nèi)存可見性,下面我們就來看看你文章對synchronized鎖的介紹,需要的朋友也可以參考一下
    2021-12-12
  • SpringCloud輪詢拉取注冊表與服務發(fā)現(xiàn)流程詳解

    SpringCloud輪詢拉取注冊表與服務發(fā)現(xiàn)流程詳解

    這篇文章主要介紹了SpringCloud輪詢拉取注冊表與服務發(fā)現(xiàn),現(xiàn)在很多創(chuàng)業(yè)公司都開始往springcloud靠了,可能是由于文檔和組件比較豐富的原因吧,畢竟是一款目前來說比較完善的微服務架構(gòu)
    2022-11-11
  • 淺談Apache Maven ToolChains的使用

    淺談Apache Maven ToolChains的使用

    Maven是java中非常有用和常用的構(gòu)建工具,基本上現(xiàn)在大型的java項目都是Maven和gradle的天下了。本文將介紹Apache Maven ToolChains的使用。
    2021-06-06
  • 在Java項目中實現(xiàn)CI/CD持續(xù)集成與持續(xù)部署

    在Java項目中實現(xiàn)CI/CD持續(xù)集成與持續(xù)部署

    這篇文章主要為大家介紹了在Java項目中實現(xiàn)CI/CD持續(xù)集成與持續(xù)部署詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • Java多線程的實現(xiàn)方式比較(兩種方式比較)

    Java多線程的實現(xiàn)方式比較(兩種方式比較)

    Java多線程實現(xiàn)方式有兩種,第一種是繼承Thread類,第二種是實現(xiàn)Runnable接口,兩種有很多差異,下面跟著本文一起學習吧
    2015-11-11
  • Java通過notify和wait實現(xiàn)線程間的通信功能

    Java通過notify和wait實現(xiàn)線程間的通信功能

    在軟件開發(fā)中,線程是實現(xiàn)并發(fā)執(zhí)行的重要手段,然而,線程之間的協(xié)作與通信卻是開發(fā)者必須重點考慮的挑戰(zhàn)之一,Java作為一種廣泛應用于多線程編程的語言,本文將深入探討Java中通過notify和wait實現(xiàn)線程間通信的機制,需要的朋友可以參考下
    2024-06-06

最新評論

乐亭县| 茂名市| 盐山县| 榆树市| 金川县| 岐山县| 厦门市| 肥乡县| 吴堡县| 长沙市| 铁岭县| 德令哈市| 葫芦岛市| 汕头市| 湖口县| 保定市| 辉南县| 遂宁市| 珲春市| 余庆县| 额济纳旗| 建水县| 屏南县| 屏东市| 宜黄县| 昌平区| 潜江市| 乳源| 河南省| 灵宝市| 兰州市| 德兴市| 安康市| 西充县| 安新县| 淳安县| 永顺县| 德格县| 堆龙德庆县| 疏附县| 东光县|