国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

如何保證緩存與數(shù)據(jù)庫雙寫時的數(shù)據(jù)一致性?

這篇具有很好參考價值的文章主要介紹了如何保證緩存與數(shù)據(jù)庫雙寫時的數(shù)據(jù)一致性?。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

背景:使用到緩存,無論是本地內(nèi)存做緩存還是使用?Redis?做緩存,那么就會存在數(shù)據(jù)同步的問題,因?yàn)榕渲眯畔⒕彺嬖趦?nèi)存中,而內(nèi)存時無法感知到數(shù)據(jù)在數(shù)據(jù)庫的修改。這樣就會造成數(shù)據(jù)庫中的數(shù)據(jù)與緩存中數(shù)據(jù)不一致的問題。

共有四種方案:

  1. 先更新數(shù)據(jù)庫,后更新緩存
  2. 先更新緩存,后更新數(shù)據(jù)庫
  3. 先刪除緩存,后更新數(shù)據(jù)庫
  4. 先更新數(shù)據(jù)庫,后刪除緩存

第一種和第二種方案,沒有人使用的,因?yàn)榈谝环N方案存在問題是:并發(fā)更新數(shù)據(jù)庫場景下,會將臟數(shù)據(jù)刷到緩存。

第二種方案存在的問題是:如果先更新緩存成功,但是數(shù)據(jù)庫更新失敗,則肯定會造成數(shù)據(jù)不一致。

目前主要用第三和第四種方案。

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

該方案也會出問題,此時來了兩個請求,請求?A(更新操作)?和請求?B(查詢操作)

  1. 請求A進(jìn)行寫操作,刪除緩存
  2. 請求B查詢發(fā)現(xiàn)緩存不存在
  3. 請求B去數(shù)據(jù)庫查詢得到舊值
  4. 請求B將舊值寫入緩存
  5. 請求A將新值寫入數(shù)據(jù)庫

上述情況就會導(dǎo)致不一致的情形出現(xiàn)。而且,如果不采用給緩存設(shè)置過期時間策略,該數(shù)據(jù)永遠(yuǎn)都是臟數(shù)據(jù)。

答案一:延時雙刪

最簡單的解決辦法延時雙刪

使用偽代碼如下:
?

public void write(String?key,Object?data){
        Redis.delKey(key);
????????db.updateData(data);
        Thread.sleep(1000);
        Redis.delKey(key);
    }

轉(zhuǎn)化為中文描述就是?(1)先淘汰緩存?(2)再寫數(shù)據(jù)庫(這兩步和原來一樣)?(3)休眠1秒,再次淘汰緩存,這么做,可以將1秒內(nèi)所造成的緩存臟數(shù)據(jù),再次刪除。確保讀請求結(jié)束,寫請求可以刪除讀請求造成的緩存臟數(shù)據(jù)。自行評估自己的項(xiàng)目的讀數(shù)據(jù)業(yè)務(wù)邏輯的耗時,寫數(shù)據(jù)的休眠時間則在讀數(shù)據(jù)業(yè)務(wù)邏輯的耗時基礎(chǔ)上,加幾百ms即可。

如果使用的是?Mysql?的讀寫分離的架構(gòu)的話,那么其實(shí)主從同步之間也會有時間差。

如何保證緩存與數(shù)據(jù)庫雙寫時的數(shù)據(jù)一致性?,Redis,緩存,數(shù)據(jù)庫,redis

主從同步時間差

此時來了兩個請求,請求?A(更新操作)?和請求?B(查詢操作)

  1. 請求?A?更新操作,刪除了?Redis
  2. 請求主庫進(jìn)行更新操作,主庫與從庫進(jìn)行同步數(shù)據(jù)的操作
  3. 請?B?查詢操作,發(fā)現(xiàn)?Redis?中沒有數(shù)據(jù)
  4. 去從庫中拿去數(shù)據(jù)
  5. 此時同步數(shù)據(jù)還未完成,拿到的數(shù)據(jù)是舊數(shù)據(jù)

此時的解決辦法就是如果是對?Redis?進(jìn)行填充數(shù)據(jù)的查詢數(shù)據(jù)庫操作,那么就強(qiáng)制將其指向主庫進(jìn)行查詢。

如何保證緩存與數(shù)據(jù)庫雙寫時的數(shù)據(jù)一致性?,Redis,緩存,數(shù)據(jù)庫,redis

從主庫中拿數(shù)據(jù)

答案二:?更新與讀取操作進(jìn)行異步串行化

異步串行化

我在系統(tǒng)內(nèi)部維護(hù)n個內(nèi)存隊(duì)列,更新數(shù)據(jù)的時候,根據(jù)數(shù)據(jù)的唯一標(biāo)識,將該操作路由之后,發(fā)送到其中一個jvm內(nèi)部的內(nèi)存隊(duì)列中(對同一數(shù)據(jù)的請求發(fā)送到同一個隊(duì)列)。讀取數(shù)據(jù)的時候,如果發(fā)現(xiàn)數(shù)據(jù)不在緩存中,并且此時隊(duì)列里有更新庫存的操作,那么將重新讀取數(shù)據(jù)+更新緩存的操作,根據(jù)唯一標(biāo)識路由之后,也將發(fā)送到同一個jvm內(nèi)部的內(nèi)存隊(duì)列中。然后每個隊(duì)列對應(yīng)一個工作線程,每個工作線程串行地拿到對應(yīng)的操作,然后一條一條的執(zhí)行。

這樣的話,一個數(shù)據(jù)變更的操作,先執(zhí)行刪除緩存,然后再去更新數(shù)據(jù)庫,但是還沒完成更新的時候,如果此時一個讀請求過來,讀到了空的緩存,那么可以先將緩存更新的請求發(fā)送到隊(duì)列中,此時會在隊(duì)列中積壓,排在剛才更新庫的操作之后,然后同步等待緩存更新完成,再讀庫。

讀操作去重

多個讀庫更新緩存的請求串在同一個隊(duì)列中是沒意義的,因此可以做過濾,如果發(fā)現(xiàn)隊(duì)列中已經(jīng)有了該數(shù)據(jù)的更新緩存的請求了,那么就不用再放進(jìn)去了,直接等待前面的更新操作請求完成即可,待那個隊(duì)列對應(yīng)的工作線程完成了上一個操作(數(shù)據(jù)庫的修改)之后,才會去執(zhí)行下一個操作(讀庫更新緩存),此時會從數(shù)據(jù)庫中讀取最新的值,然后寫入緩存中。

如果請求還在等待時間范圍內(nèi),不斷輪詢發(fā)現(xiàn)可以取到值了,那么就直接返回;如果請求等待的時間超過一定時長,那么這一次直接從數(shù)據(jù)庫中讀取當(dāng)前的舊值。(返回舊值不是又導(dǎo)致緩存和數(shù)據(jù)庫不一致了么?那至少可以減少這個情況發(fā)生,因?yàn)榈却瑫r也不是每次都是,幾率很小吧。這里我想的是,如果超時了就直接讀舊值,這時候僅僅是讀庫后返回而不放緩存)

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

這一種情況也會出現(xiàn)問題,比如更新數(shù)據(jù)庫成功了,但是在刪除緩存的階段出錯了沒有刪除成功,那么此時再讀取緩存的時候每次都是錯誤的數(shù)據(jù)了。

如何保證緩存與數(shù)據(jù)庫雙寫時的數(shù)據(jù)一致性?,Redis,緩存,數(shù)據(jù)庫,redis

此時解決方案就是利用消息隊(duì)列進(jìn)行刪除的補(bǔ)償。具體的業(yè)務(wù)邏輯用語言描述如下:

  1. 請求?A?先對數(shù)據(jù)庫進(jìn)行更新操作
  2. 在對?Redis?進(jìn)行刪除操作的時候發(fā)現(xiàn)報錯,刪除失敗
  3. 此時將Redis?的?key?作為消息體發(fā)送到消息隊(duì)列中
  4. 系統(tǒng)接收到消息隊(duì)列發(fā)送的消息后再次對?Redis?進(jìn)行刪除操作

但是這個方案會有一個缺點(diǎn)就是會對業(yè)務(wù)代碼造成大量的侵入,深深的耦合在一起,所以這時會有一個優(yōu)化的方案,我們知道對?Mysql?數(shù)據(jù)庫更新操作后再?binlog?日志中我們都能夠找到相應(yīng)的操作,那么我們可以訂閱?Mysql?數(shù)據(jù)庫的?binlog?日志對緩存進(jìn)行操作。

如何保證緩存與數(shù)據(jù)庫雙寫時的數(shù)據(jù)一致性?,Redis,緩存,數(shù)據(jù)庫,redis

利用訂閱?binlog?刪除緩存文章來源地址http://www.zghlxwxcb.cn/news/detail-820570.html

到了這里,關(guān)于如何保證緩存與數(shù)據(jù)庫雙寫時的數(shù)據(jù)一致性?的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Redis---數(shù)據(jù)庫和緩存如何保證一致性?

    用「讀 + 寫」請求的并發(fā)的場景來分析: 假如某個用戶數(shù)據(jù)在緩存中不存在,請求 A 讀取數(shù)據(jù)時從數(shù)據(jù)庫中查詢到年齡為 20,在未寫入緩存中時另一個請求 B 更新數(shù)據(jù)。它更新數(shù)據(jù)庫中的年齡為 21,并且清空緩存。這時請求 A 把從數(shù)據(jù)庫中讀到的年齡為 20 的數(shù)據(jù)寫入到緩存

    2024年01月24日
    瀏覽(27)
  • Redis如何保證緩存和數(shù)據(jù)庫一致性?

    現(xiàn)在我們在面向增刪改查開發(fā)時,數(shù)據(jù)庫數(shù)據(jù)量大時或者對響應(yīng)要求較快,我們就需要用到Redis來拿取數(shù)據(jù)。 Redis:是一種高性能的內(nèi)存數(shù)據(jù)庫,它將數(shù)據(jù)以鍵值對的形式存儲在內(nèi)存中,具有讀寫速度快、支持多種數(shù)據(jù)類型、原子性操作、豐富的特性等優(yōu)勢。 優(yōu)勢: 性能極高

    2024年01月16日
    瀏覽(40)
  • Redis緩存MySQL數(shù)據(jù)庫存儲二者如何保證數(shù)據(jù)一致性

    在大型互聯(lián)網(wǎng)應(yīng)用中,由于數(shù)據(jù)庫讀寫頻繁、壓力大等原因,我們通常會使用緩存來減少數(shù)據(jù)庫的訪問次數(shù),提高系統(tǒng)的性能。而Redis作為一個高性能的內(nèi)存數(shù)據(jù)庫,成為了緩存的首選方案之一。但是,緩存和數(shù)據(jù)庫之間存在數(shù)據(jù)一致性的問題,如何解決這個問題呢?本文將

    2023年04月19日
    瀏覽(26)
  • redis面試題目-如何保證數(shù)據(jù)庫與緩存的數(shù)據(jù)一致性

    原視頻:https://www.bilibili.com/video/BV1Km4y1r75f?p=62vd_source=fa75329ae3880aa55609265a0e9f5d34 由于緩存和數(shù)據(jù)庫是分開的,無法做到原子性的同時進(jìn)行數(shù)據(jù)修改,可能出現(xiàn)緩存更新失敗,或者數(shù)據(jù)庫更新失敗的情況,這時候會出現(xiàn)數(shù)據(jù)不一致,影響前端業(yè)務(wù) 先更新數(shù)據(jù)庫,再更新緩存。緩

    2024年02月05日
    瀏覽(27)
  • 如何保證Redis緩存和數(shù)據(jù)庫的一致性問題

    熟練掌握Redis緩存技術(shù)? 那么請問Redis緩存中有幾種讀寫策略,又是如何保證與數(shù)據(jù)庫的一致性問題 今天來聊一聊常用的三種緩存讀寫策略 首先我們來思考一個問題 寫 先更新緩存 再更新數(shù)據(jù)庫 首先如果緩存更新成功但數(shù)據(jù)庫更新失敗,會導(dǎo)致數(shù)據(jù)不一致的問題 其次當(dāng)請求

    2024年02月14日
    瀏覽(23)
  • redis的緩存更新策略以及如何保證redis與數(shù)據(jù)庫的數(shù)據(jù)一致性

    redis的緩存更新策略有這么幾種: 1、由應(yīng)用直接和redis以及數(shù)據(jù)庫相連接: ?? ??? ?查詢數(shù)據(jù)時,應(yīng)用去redis中查詢,查不到的話再由應(yīng)用去數(shù)據(jù)庫中查詢,并將查詢結(jié)果放在redis; ?? ??? ?更新數(shù)據(jù)時,由應(yīng)用去觸發(fā)redis數(shù)據(jù)的刪除以及數(shù)據(jù)庫的update。 2、應(yīng)用只跟redi

    2024年02月13日
    瀏覽(25)
  • REDIS21_緩存雙寫一致方案、先更新數(shù)據(jù)庫再刪除緩存

    REDIS21_緩存雙寫一致方案、先更新數(shù)據(jù)庫再刪除緩存

    ①. 緩存雙寫一致性,談?wù)勀愕睦斫?如果redis中有數(shù)據(jù),需要和數(shù)據(jù)庫中的值相同 如果redis中無數(shù)據(jù),數(shù)據(jù)庫中的值要是最新值 ②. 什么時候同步直寫? 小數(shù)據(jù),某條、某一小戳熱點(diǎn)數(shù)據(jù),要求立刻變更,可以前臺服務(wù)降價一下,后臺馬上同步直寫 ③. 什么時候異步緩寫? 正常業(yè)務(wù),馬

    2023年04月08日
    瀏覽(17)
  • 高并發(fā)下數(shù)據(jù)一致性問題:數(shù)據(jù)庫+緩存雙寫模式分析

    高并發(fā)下數(shù)據(jù)一致性問題:數(shù)據(jù)庫+緩存雙寫模式分析

    隨著互聯(lián)網(wǎng)業(yè)務(wù)的發(fā)展,其中越來越多場景使用了緩存來提升服務(wù)質(zhì)量。從系統(tǒng)角度而言, 緩存的主要目標(biāo)是減輕數(shù)據(jù)庫壓力(特別是讀取壓力)并提高服務(wù)響應(yīng)速度 。引入緩存就不可避免會涉及到緩存與業(yè)務(wù)數(shù)據(jù)庫數(shù)據(jù)一致性的問題,而不同的業(yè)務(wù)場景對數(shù)據(jù)一致性的要

    2024年02月09日
    瀏覽(16)
  • Redis - 做緩存時高并發(fā)問題:緩存穿透、擊穿、雪崩,數(shù)據(jù)庫緩存雙寫不一致

    Redis - 做緩存時高并發(fā)問題:緩存穿透、擊穿、雪崩,數(shù)據(jù)庫緩存雙寫不一致

    當(dāng)用戶訪問的數(shù)據(jù)既不在緩存也不在數(shù)據(jù)庫中時,就會導(dǎo)致每個用戶查詢都會“穿透” 緩存“直抵”數(shù)據(jù)庫。這種情況就稱為緩存穿透。當(dāng)高度發(fā)的訪問請求到達(dá)時,緩存穿透不 僅增加了響應(yīng)時間,而且還會引發(fā)對 DBMS 的高并發(fā)查詢,這種高并發(fā)查詢很可能會導(dǎo)致 DBMS 的崩

    2024年02月04日
    瀏覽(19)
  • 緩存與數(shù)據(jù)庫雙寫一致性幾種策略分析

    作者:京東零售?于瀧 在高并發(fā)場景中,為防止大量請求直接訪問數(shù)據(jù)庫,緩解數(shù)據(jù)庫壓力,常用的方式一般會增加緩存層起到緩沖作用,減少數(shù)據(jù)庫壓力。引入緩存,就會涉及到緩存與數(shù)據(jù)庫中數(shù)據(jù)如何保持一致性問題,本文將對幾種緩存與數(shù)據(jù)庫保證數(shù)據(jù)一致性的使用方

    2023年04月19日
    瀏覽(35)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包