精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

Redis緩存更新一致性的方式

jf_ro2CN3Fa ? 來源:博客園 ? 作者:Finley ? 2022-11-21 10:40 ? 次閱讀

當執(zhí)行寫操作后,需要保證從緩存讀取到的數(shù)據(jù)與數(shù)據(jù)庫中持久化的數(shù)據(jù)是一致的,因此需要對緩存進行更新。

因為涉及到數(shù)據(jù)庫和緩存兩步操作,難以保證更新的原子性。

在設計更新策略時,我們需要考慮多個方面的問題:

對系統(tǒng)吞吐量的影響:比如更新緩存策略產(chǎn)生的數(shù)據(jù)庫負載小于刪除緩存策略的負載

并發(fā)安全性:并發(fā)讀寫時某些異常操作順序可能造成數(shù)據(jù)不一致,如緩存中長期保存過時數(shù)據(jù)

更新失敗的影響:若某個操作失敗,如何對業(yè)務影響降到最小

檢測和修復故障的難度: 操作失敗導致的錯誤會在日志留下詳細的記錄容易檢測和修復。并發(fā)問題導致的數(shù)據(jù)錯誤沒有明顯的痕跡難以發(fā)現(xiàn),且在流量高峰期更容易產(chǎn)生并發(fā)錯誤產(chǎn)生的業(yè)務風險較大。

更新緩存有兩種方式:

刪除失效緩存: 讀取時會因為未命中緩存而從數(shù)據(jù)庫中讀取新的數(shù)據(jù)并更新到緩存中

更新緩存: 直接將新的數(shù)據(jù)寫入緩存覆蓋過期數(shù)據(jù)

更新緩存和更新數(shù)據(jù)庫有兩種順序:

先數(shù)據(jù)庫后緩存

先緩存后數(shù)據(jù)庫

兩兩組合共有四種更新策略,現(xiàn)在我們逐一進行分析。

并發(fā)問題通常由于后開始的線程卻先完成操作導致,我們把這種現(xiàn)象稱為“搶跑”。下面我們逐一分析四種策略中“搶跑”帶來的錯誤。

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

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

可能存在讀寫線程競爭導致的并發(fā)錯誤:

基于 Spring Boot + MyBatis Plus + Vue & Element 實現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權限、多租戶、數(shù)據(jù)權限、工作流、三方登錄、支付、短信、商城等功能

項目地址:https://github.com/YunaiV/ruoyi-vue-pro

視頻教程:https://doc.iocoder.cn/video/

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

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

該策略同樣存在讀寫線程競爭導致數(shù)據(jù)不一致的問題:

ec4a5aa0-68b7-11ed-8abf-dac502259ad0.png

也可能因為兩個寫線程競爭導致并發(fā)錯誤:

ec6d143c-68b7-11ed-8abf-dac502259ad0.png

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權限、多租戶、數(shù)據(jù)權限、工作流、三方登錄、支付、短信、商城等功能

項目地址:https://github.com/YunaiV/yudao-cloud

視頻教程:https://doc.iocoder.cn/video/

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

可能發(fā)生的并發(fā)錯誤:

ec97c696-68b7-11ed-8abf-dac502259ad0.png

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

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

因為數(shù)據(jù)庫因為鍵約束導致寫入失敗的可能性較高,所以這種策略風險較大。

可能發(fā)生的并發(fā)錯誤:

ecd69df8-68b7-11ed-8abf-dac502259ad0.png

兩個寫線程競爭也會導致數(shù)據(jù)不一致:

ecf7b934-68b7-11ed-8abf-dac502259ad0.png

解決方案

使用 CAS

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

funcCAS(oldVal,newVal){
ifcache.get()==oldVal{
cache.set(newVal)
}
}

時間 線程A 線程B 數(shù)據(jù)庫 緩存
0 v0 v0
1 更新數(shù)據(jù)庫為 v1 v1 v0
2 更新數(shù)據(jù)庫為 v2 v2 v0
3 執(zhí)行 CAS 操作:當且僅當緩存中為 v0 時將 v2 寫入緩存 v2 v2
4 執(zhí)行 CAS 操作:當且僅當緩存中為 v0 時將v1寫入緩存。當前緩存為 v2 故放棄寫緩存 v2 v2

由上圖可見,CAS 可以有效的避免并發(fā)錯誤的發(fā)生。

目前一些兼容 Redis 協(xié)議的中間件已經(jīng)提供了 CAS 命令的支持,比如阿里的 Tair 以及騰訊的 Tendis。

Redis 官方提供了 Watch + 事務的方法來支持 CAS, 或者使用 redis 中 lua 腳本原子性執(zhí)行的特點來實現(xiàn) CAS。不過由于代碼較為復雜,這兩種方案都不常見。

使用分布式鎖

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

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

時間 線程A 線程B 數(shù)據(jù)庫 緩存
0 v0 v0
1 獲取排它鎖 v0 v0
2 更新數(shù)據(jù)庫為 v1 v1 v0
3 更新緩存為 v1 v1 v1
4 等待排它鎖 v1 v1
5 釋放排它鎖 v1 v1
6 獲得排它鎖 v1 v1
7 更新數(shù)據(jù)庫為 v2 v2 v1
8 更新緩存為 v2 v2 v2
9 釋放排它鎖 v2 v2

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

異步更新

阿里開源了 MySQL 數(shù)據(jù)庫binlog的增量訂閱和消費組件 - canal。canal 模擬從庫獲得主庫的 binlog 更新,然后將更新數(shù)據(jù)寫入 MQ 或直接進行消費。

我們可以讓API服務器只負責寫入數(shù)據(jù)庫,另一個線程訂閱數(shù)據(jù)庫 binlog 增量進行緩存更新。

因為 binlog 是有序的,因此可以避免兩個寫線程競爭。但我們?nèi)匀恍枰鉀Q讀寫線程競爭的問題:

ed2a5a56-68b7-11ed-8abf-dac502259ad0.png

這里同樣可以 CAS 解千愁:

ed8614a4-68b7-11ed-8abf-dac502259ad0.png

延時雙刪

使用刪除緩存策略時讀線程先開始卻后寫緩存會導致不一致,那么我們在讀線程結束后再次清除緩存是不是就可以解除錯誤狀態(tài)了?延時雙刪就是寫線程等待一段時間“確保”讀線程都結束后再次刪除緩存,以此清除可能的錯誤緩存數(shù)據(jù)。

eda9ebb8-68b7-11ed-8abf-dac502259ad0.png

理論上我們無法給出一個時間來“確保”讀線程都結束,所以仍有存在并發(fā)問題的可能。但是延時雙刪實現(xiàn)成本很低而且極大的減少了并發(fā)問題出現(xiàn)的概率,不失為一種簡單實用的手段。






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • CAS
    CAS
    +關注

    關注

    0

    文章

    34

    瀏覽量

    15183
  • MYSQL數(shù)據(jù)庫

    關注

    0

    文章

    95

    瀏覽量

    9380
  • Redis
    +關注

    關注

    0

    文章

    371

    瀏覽量

    10846

原文標題:講講 Redis 緩存更新一致性

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關推薦

    介紹ARM存儲一致性模型的相關知識

    今天要說的這個是存儲一致性(memory consistency),不要跟前面講過緩存一致性(cache coherence)混淆了。
    的頭像 發(fā)表于 02-14 09:19 ?1783次閱讀

    如何解決數(shù)據(jù)庫與緩存一致性

    數(shù)據(jù)庫壓力。當乘客購買成功之后,數(shù)據(jù)庫發(fā)生了變化,需要及時更新緩存中的數(shù)據(jù),以便于其他乘客能從緩存中及時獲取最新車票信息。這就是緩存一致性
    的頭像 發(fā)表于 09-25 15:25 ?1049次閱讀
    如何解決數(shù)據(jù)庫與<b class='flag-5'>緩存</b><b class='flag-5'>一致性</b>

    Redis緩存和MySQL數(shù)據(jù)不一致原因和解決方案

    高并發(fā)架構系列:Redis緩存和MySQL數(shù)據(jù)一致性方案詳解
    發(fā)表于 03-27 15:55

    一致性規(guī)劃研究

    針對一致性規(guī)劃的高度求解復雜度,分析主流一致性規(guī)劃器的求解策略,給出影響一致性規(guī)劃器性能的主要因素:啟發(fā)信息的有效,信念狀態(tài)表示方法的緊湊
    發(fā)表于 04-06 08:43 ?12次下載

    加速器一致性接口

    提供異步緩存一致性直接訪問PS的入口。處理器可以標記ACP上的傳輸為一致性或非一致性。PL端的AXI主機通過ARUSERS[1:0]指示是否為一致性
    發(fā)表于 11-17 15:04 ?3597次閱讀

    基于軌跡標簽的謠言一致性維護算法

    針對發(fā)布/訂閱系統(tǒng)中緩存副本一致性維護問題,首先,對原有基于謠言的一致性維護算法進行改進,提出種基于軌跡標簽的謠言一致性維護算法。該算法通
    發(fā)表于 12-17 11:35 ?0次下載
    基于軌跡標簽的謠言<b class='flag-5'>一致性</b>維護算法

    Cache一致性協(xié)議優(yōu)化研究

    問題的由來.總結了多核時代高速緩存一致性協(xié)議設計的關鍵問題,綜述了近年來學術界對一致性的研究.從程序訪存行為模式、目錄組織結構、一致性粒度、一致性
    發(fā)表于 12-30 15:04 ?0次下載
    Cache<b class='flag-5'>一致性</b>協(xié)議優(yōu)化研究

    自主駕駛系統(tǒng)將使用緩存一致性互連IP和非一致性互連IP

    代ASIL B(D)自主駕駛系統(tǒng)將使用符合ISO 26262標準的緩存一致性互連IP和非一致性互連IP來實現(xiàn)。 美國加利福尼亞州坎貝爾2019年4月26日消息—Arteris IP
    的頭像 發(fā)表于 05-09 17:13 ?3191次閱讀

    管理基于Cortex?-M7的MCU的高速緩存一致性

    本文檔概述了不同場景下的高速緩存一致性問題,并就如何管理或避免高速緩存一致性問題提供了些方法建議。
    發(fā)表于 04-01 10:12 ?5次下載
    管理基于Cortex?-M7的MCU的高速<b class='flag-5'>緩存</b><b class='flag-5'>一致性</b>

    介紹下cpu緩存一致性(MESI協(xié)議)

    之前介紹了java并發(fā)包的cas原理和java內(nèi)存模型,這篇我們介紹下cpu緩存一致性原理,可以幫助我們更好的理解cas的底層原理。
    的頭像 發(fā)表于 06-09 16:01 ?4569次閱讀
    介紹下cpu<b class='flag-5'>緩存</b><b class='flag-5'>一致性</b>(MESI協(xié)議)

    管理基于Cortex-M7的MCU的高速緩存一致性

    電子發(fā)燒友網(wǎng)站提供《管理基于Cortex-M7的MCU的高速緩存一致性.pdf》資料免費下載
    發(fā)表于 09-25 10:11 ?0次下載
    管理基于Cortex-M7的MCU的高速<b class='flag-5'>緩存</b><b class='flag-5'>一致性</b>

    如何保證緩存一致性

    “ 本文的參考文章是2022年HOT 34上Intel Rob Blakenship關于CXL緩存一致性篇介紹。”
    的頭像 發(fā)表于 10-19 17:42 ?1035次閱讀
    如何保證<b class='flag-5'>緩存</b><b class='flag-5'>一致性</b>

    redis與mysql如何保持數(shù)據(jù)一致性

    Redis和MySQL是兩個常用的數(shù)據(jù)庫系統(tǒng),它們都有自己的特點和用途。在某些場景下,我們可能需要將Redis和MySQL進行結合使用,并保持數(shù)據(jù)的一致性
    的頭像 發(fā)表于 11-16 11:27 ?906次閱讀

    Redis緩存與Mysql如何保證一致性

    基本流程就是客戶端A請求,先去刪除緩存,然后將數(shù)據(jù)寫入數(shù)據(jù)庫,此時客戶端B查詢先去查詢緩存緩存沒有返回,去查數(shù)據(jù)庫,此時還沒有完成主從同步,拿到是從庫的舊數(shù)據(jù),然后將舊數(shù)據(jù)進行緩存
    的頭像 發(fā)表于 12-02 14:23 ?891次閱讀
    <b class='flag-5'>Redis</b><b class='flag-5'>緩存</b>與Mysql如何保證<b class='flag-5'>一致性</b>?

    異構計算下緩存一致性的重要

    在眾多回復中,李博杰同學的回答被認為質(zhì)量最高。他首先將緩存一致性分為兩個主要場景:是主機內(nèi)CPU與設備間的一致性;二是跨主機的一致性
    的頭像 發(fā)表于 10-24 17:00 ?288次閱讀
    異構計算下<b class='flag-5'>緩存</b><b class='flag-5'>一致性</b>的重要<b class='flag-5'>性</b>