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

Redis緩存雙寫一致性

這篇具有很好參考價(jià)值的文章主要介紹了Redis緩存雙寫一致性。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1、緩存雙寫一致性的理解

Redis緩存雙寫一致性
如果redis中有數(shù)據(jù):需要和數(shù)據(jù)庫中的值相同
如果redis中無數(shù)據(jù):數(shù)據(jù)庫中的值要是最新值,且準(zhǔn)備回寫redis

緩存按照操作來分,可細(xì)分為兩種:只讀緩存和讀寫緩存

只讀緩存很簡單:就是Redis只做查詢,有就是有,沒有就是沒有,不會(huì)再進(jìn)一步訪問MySQL,不再需要會(huì)寫機(jī)制

大部分都是讀寫緩存,又分為兩種:
同步直寫策略
寫數(shù)據(jù)庫后也同步寫redis緩存,緩存和數(shù)據(jù)庫中的數(shù)據(jù)一 致
對于讀寫緩存來說,要想保證緩存和數(shù)據(jù)庫中的數(shù)據(jù)一致,就要采用同步直寫策略
比如特別重要的數(shù)據(jù)、熱點(diǎn)敏感數(shù)據(jù),例如充值后就需要立馬更新,及時(shí)生效

異步緩寫策略
正常業(yè)務(wù)運(yùn)行中,mysq|數(shù)據(jù)變動(dòng)了,但是可以在業(yè)務(wù)上容許出現(xiàn)一定時(shí)間后才作用于redis,比如倉庫、物流系統(tǒng)、積分變更
異常情況出現(xiàn)了,不得不將失敗的動(dòng)作重新修補(bǔ),有可能需要借助kafka或者RabbitMQ等消息中間件,實(shí)現(xiàn)重試重寫
Redis緩存雙寫一致性

業(yè)務(wù)流程寫得沒錯(cuò),對于QPS(每秒查詢率)小于1000可以使用,但是對于高并發(fā)場景不適于。比如在高并發(fā)場景下,許多線程幾乎同時(shí)(時(shí)間間隔得不那么開)查詢相同的值,由于redis中沒有,會(huì)全部直接打到MySQL上,MySQL可能就會(huì)被打宕機(jī),即使沒宕機(jī),這些線程又會(huì)進(jìn)行大量的回寫,而且回寫的還是同一個(gè)值。這里的本質(zhì)就是:查詢MySQL和回寫不是原子操作。

對于上述情況,需要采用雙檢測加鎖策略,類似于單例模式中的懶漢模式(可以采用雙檢測加鎖策略實(shí)現(xiàn))

多個(gè)線程同時(shí)去查詢數(shù)據(jù)庫的這條數(shù)據(jù),那么我們可以在第一個(gè)查詢數(shù)據(jù)的請求上使用一個(gè)互斥鎖來鎖住它。
其他的線程走到這一步拿不到鎖就等著,等第一個(gè)線程查詢到了數(shù)據(jù),然后做緩存。
后面的線程進(jìn)來發(fā)現(xiàn)已經(jīng)有緩存了,就直接走緩存。

Redis緩存雙寫一致性

2、數(shù)據(jù)庫和緩存一致性的幾種更新策略

目的:無論怎么操作,我們要達(dá)到最終一致性

給緩存設(shè)置過期時(shí)間,定期清理緩存并回寫,是保證最終一致性的解決方案。
我們可以對存入緩存的數(shù)據(jù)設(shè)置過期時(shí)間,所有的寫操作以數(shù)據(jù)庫為準(zhǔn),對緩存操作只是盡最大努力即可。也就是說如果數(shù)據(jù)庫寫成功,緩存更新失敗,那么只要到達(dá)過期時(shí)間,則后面的讀請求自然會(huì)從數(shù)據(jù)庫中讀取新值然后回填緩存,達(dá)到一致性,切記,要以mysql的數(shù)據(jù)庫寫入庫為準(zhǔn)。

可以停機(jī)的情況下
掛牌報(bào)錯(cuò),凌晨升級,溫馨提示,服務(wù)降級
單線程,這樣重量級的數(shù)據(jù)操作最好不要多線程

不可以停機(jī)的情況,則有4種更新策略

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

異常問題1:

  1. 先更新mysql的某商品的庫存,當(dāng)前商品的庫存是100,更新為99個(gè)
  2. 先更新mysq|修改為99成功,然后更新redis
  3. 此時(shí)假設(shè)異常出現(xiàn),更新redis失敗了,這導(dǎo)致mysq|里面的庫存是99而redis里面的還是100
  4. 上述發(fā)生,會(huì)讓數(shù)據(jù)庫里面和緩存redis里面數(shù)據(jù)不一致,讀到redis臟數(shù)據(jù)

例如:正當(dāng)需要更新redis的數(shù)據(jù)時(shí),此時(shí)可能master主機(jī)宕機(jī),salve正在處于上位(成為新的master)的過程,沒時(shí)間來回應(yīng)更新redis的數(shù)據(jù),或者更新redis的操作丟失,這就會(huì)導(dǎo)致mysql更新成功,redis更新失敗,后續(xù)所有讀操作都讀到了臟數(shù)據(jù)

異常問題2:

A、B兩個(gè)線程同時(shí)發(fā)起調(diào)用(實(shí)際上可能會(huì)存在更多的線程)
正常邏輯

  1. 線程A更新mysql中的某個(gè)值,例如a,更新為100
  2. 線程A更新redis中的a為100
  3. 線程B更新mysql中的a,更新為80
  4. 線程B更新redis中的a為80

異常邏輯
多線程環(huán)境下,A、B兩個(gè)線程有快有慢,有前有后有并行

  1. 線程A更新mysql中的a,更新為100
  2. 線程B更新mysql中的a,更新為80
  3. 線程B更新完mysql,立刻回寫更新redis中的a為80
  4. 線程A更新redis中的a為100

最終結(jié)果,mysq|和redis數(shù)據(jù)不一 致

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

從技術(shù)上可以做,但不太推薦,業(yè)務(wù)上一般把mysq|作為底單數(shù)據(jù)庫,保證最后解釋

異常問題

正常邏輯
A、B兩個(gè)線程同時(shí)發(fā)起調(diào)用(實(shí)際上可能會(huì)存在更多的線程)

  1. 線程A更新redis中的a為100
  2. 線程A更新mysql中的a為100
  3. 線程B更新redis中的a為80
  4. 線程B更新mysql中的a為80

異常邏輯
多線程環(huán)境下,A、B兩個(gè)線程有快有慢,有前有后有并行

  1. 線程A更新redis中的a為100
  2. 線程B更新redis中的a為80
  3. 線程B更新redis中的a為80
  4. 線程A更新mysql中的a為100

最終結(jié)果,mysq|和redis數(shù)據(jù)不一 致

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

異常問題,先刪除緩存,再更新數(shù)據(jù)庫(不進(jìn)行回寫),等到再次查詢時(shí),才進(jìn)行回寫操作

  1. A線程先成功刪除了redis里面的數(shù)據(jù),然后去更新mysq|,此時(shí)mysq|正在更新中,還沒有結(jié)束(比如網(wǎng)路延時(shí),或者還沒有commit)
  2. 線程B突然要來讀取redis緩存數(shù)據(jù),由于redis里面的數(shù)據(jù)是空的,線程B就需要去mysql當(dāng)中讀取數(shù)據(jù),此時(shí)數(shù)據(jù)還是舊值
  3. 線程B從mysql中讀取到舊值,由于redis中沒有緩存,線程B會(huì)進(jìn)行回寫操作,把舊值寫回redis(剛剛被A線程刪除的舊數(shù)據(jù)又被寫回進(jìn)redis)
  4. A線程終于將數(shù)據(jù)更新成功
  5. 后續(xù)的所有讀操作都是讀的臟數(shù)據(jù)

Redis緩存雙寫一致性
總結(jié):如果數(shù)據(jù)庫更新失敗或超時(shí)或返回不及時(shí),導(dǎo)致B線程請求訪問緩存時(shí)發(fā)現(xiàn)redis里面沒數(shù)據(jù),緩存缺失,B再去讀取mysq|時(shí),從數(shù)據(jù)庫中讀取到舊值,還寫回redis, 導(dǎo)致A白干了

如何解決上訴異常

采用延時(shí)雙刪策略

  1. 線程A先成功刪除redis緩存
  2. 線程A更新數(shù)據(jù)庫(更新可能還沒有完成)
  3. 線程A更新成功后,先sleep幾秒(這幾秒表示其他業(yè)務(wù)邏輯導(dǎo)致耗時(shí)延時(shí))
  4. 線程A再次刪除redis緩存
  5. 線程B的讀取+回寫一定是在線程A第二次刪除redis緩存之前

加上sleep的這段時(shí)間,就是為了讓線程B能夠先從數(shù)據(jù)庫讀取數(shù)據(jù),再把缺失的數(shù)據(jù)寫入緩存,然后,線程A再進(jìn)行刪除。所以,線程A sleep的時(shí)間,就需要大于線程B讀取數(shù)據(jù)再寫入緩存的時(shí)間這樣一來,其它線程讀取數(shù)據(jù)時(shí),會(huì)發(fā)現(xiàn)緩存缺失,所以會(huì)從數(shù)據(jù)庫中讀取最新值。因?yàn)檫@個(gè)方案會(huì)在第一次刪除緩存值后,延遲一段時(shí)間再次進(jìn)行刪除,所以我們也把它叫做"延遲雙刪"
這么做的目的,就是確保讀請求結(jié)束,寫請求可以刪除讀請求造成的緩存臟數(shù)據(jù)。

線程A刪除完成之后,休眠的時(shí)間該如何確定呢?

方案1:

在業(yè)務(wù)程序運(yùn)行的時(shí)候,統(tǒng)計(jì)下線程讀數(shù)據(jù)和寫緩存的操作時(shí)間,自行評估自己的項(xiàng)目的讀數(shù)據(jù)業(yè)務(wù)邏輯的耗時(shí),以此為基礎(chǔ)來進(jìn)行估算。然后寫數(shù)據(jù)的休眠時(shí)間則在讀數(shù)據(jù)業(yè)務(wù)邏輯的耗時(shí)基礎(chǔ)上加百毫秒即可。

方案2:

新啟動(dòng)一個(gè)后臺(tái)監(jiān)控程序,比如WatchDog監(jiān)控程序

這種同步淘汰策略,吞吐量降低了怎么辦?

將第二次刪除作為異步操作,讓一個(gè)子線程進(jìn)行異步刪除,這樣,寫的請求就不用沉睡一段時(shí)間后了,再返回。這么做,加大吞吐量。

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

異常問題

  1. 線程A更新數(shù)據(jù)庫中的值
  2. 線程A還沒有來得及刪除緩存的值,此時(shí)線程B讀取緩存,讀取的是緩存舊值
  3. 線程A刪除緩存
  4. 其他線程進(jìn)行redis讀取操作,利用回寫策略,把緩存更新為最新

雖然會(huì)出現(xiàn)緩存刪除失敗或者來不及,導(dǎo)致請求再次訪問redis時(shí)緩存命中,讀取到的是緩存舊值的這種情況,但是這個(gè)方案是最穩(wěn)妥的

為了解決上訴問題,可以使用消息中間件,來保證數(shù)據(jù)的最終一致性

Redis緩存雙寫一致性

流程:

(1)更新數(shù)據(jù)庫數(shù)據(jù)
(2) 數(shù)據(jù)庫會(huì)將操作信息寫入binlog日志當(dāng)中
(3) 訂閱程序提取出所需要的數(shù)據(jù)以及key
(4) 另起一段非業(yè)務(wù)代碼,獲得該信息
(5)嘗試刪除緩存操作,發(fā)現(xiàn)刪除失敗
(6)將這些信息發(fā)送至消息隊(duì)列
(7)重新從消息隊(duì)列中獲得該數(shù)據(jù),重試操作

1、可以把要?jiǎng)h除的緩存值或者是要更新的數(shù)據(jù)庫值暫存到消息隊(duì)列中(例如使用Kafka/RabbitMQ等)。
2、當(dāng)程序沒有能夠成功地刪除緩存值或者是更新數(shù)據(jù)庫值時(shí),可以從消息隊(duì)列中重新讀取這些值,然后再次進(jìn)行刪除或更新。
3、如果能夠成功地刪除或更新,我們就要把這些值從消息隊(duì)列中去除,以免重復(fù)操作,此時(shí),我們也可以保證數(shù)據(jù)庫和緩存的數(shù)據(jù)一致了,否則還需要再次進(jìn)行重試
4、如果重試超過的一定次數(shù)后還是沒有成功,我們就需要向業(yè)務(wù)層發(fā)送報(bào)錯(cuò)信息了,通知運(yùn)維人員。

對于Redis和MySQL(或者其它數(shù)據(jù)庫),不能保證數(shù)據(jù)實(shí)時(shí)一致性,也就說無論哪一方進(jìn)行了修改,另一方都能立刻同步,因?yàn)槠渲羞€存在許多不確定因素,例如網(wǎng)絡(luò)延時(shí),因此我們需要保證的是最終一致性文章來源地址http://www.zghlxwxcb.cn/news/detail-415869.html

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

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

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

相關(guān)文章

  • Redis緩存雙寫一致性之更新策略

    Redis緩存雙寫一致性之更新策略

    你只要用緩存,就可能會(huì)涉及到redis緩存與數(shù)據(jù)庫雙存儲(chǔ)雙寫,你只要是雙寫,就一定會(huì)有數(shù)據(jù)一致性的問題,那么你如何解決一致性問題? 雙寫一致性,你先動(dòng)緩存redis還是數(shù)據(jù)庫mysql哪一個(gè)?why? 延時(shí)雙刪你做過嗎?會(huì)有哪些問題? 有這么一種情況,微服務(wù)查詢r(jià)edis無m

    2024年02月05日
    瀏覽(28)
  • Redis緩存問題:穿透,擊穿,雪崩,雙寫一致性等

    Redis緩存問題:穿透,擊穿,雪崩,雙寫一致性等

    在高并發(fā)場景下,數(shù)據(jù)庫往往是最薄弱的環(huán)節(jié),我們通常選擇使用 redis 來進(jìn)行緩存,以起到緩沖作用,來降低數(shù)據(jù)庫的壓力,但是一旦緩存出現(xiàn)問題,也會(huì)導(dǎo)致數(shù)據(jù)庫瞬間壓力過大甚至崩潰,從而導(dǎo)致整個(gè)系統(tǒng)崩潰.今天就聊聊常見的 redis 緩存問題. 緩存擊穿 緩存擊穿一般指redis中的一

    2024年04月27日
    瀏覽(31)
  • 【redis】緩存雙寫一致性之工程落地實(shí)現(xiàn)(下)

    【redis】緩存雙寫一致性之工程落地實(shí)現(xiàn)(下)

    提示:以下是本篇文章正文內(nèi)容,下面案例可供參考 如何監(jiān)聽MySQL的變動(dòng)? MySQL有一個(gè)binlog日志 偽裝成從機(jī),從主機(jī)獲取二進(jìn)制文件 配置不在詳述 配置不再詳述 a、業(yè)務(wù)類: 當(dāng)MySQL進(jìn)行增刪改操作時(shí),后臺(tái)的canal會(huì)立刻監(jiān)聽捕捉到MySQL的二進(jìn)制binlog日志文件改動(dòng),并通過Jav

    2023年04月19日
    瀏覽(22)
  • redis高級篇 緩存雙寫一致性之更新策略

    redis高級篇 緩存雙寫一致性之更新策略

    緩存通用查詢3部曲 redis 中數(shù)據(jù),返回redis 中的數(shù)據(jù) redis 中沒有,查詢數(shù)據(jù)庫并返回 完成第二部的同時(shí),將數(shù)據(jù)庫查詢結(jié)果寫到redis,redis和數(shù)據(jù)庫數(shù)據(jù)一致. 談?wù)勲p寫一致性的理解 1.如果redis 中有數(shù)據(jù):需要和數(shù)據(jù)庫中的相同 2.如果redis 中無數(shù)據(jù): 數(shù)據(jù)庫中的值如果是最新的

    2024年02月06日
    瀏覽(21)
  • Redis雙寫一致性?

    Redis雙寫一致性?

    雙寫一致性:當(dāng)修改了數(shù)據(jù)庫的數(shù)據(jù)也要同時(shí)更新緩存的數(shù)據(jù),緩存和數(shù)據(jù)庫的數(shù)據(jù)要保持一致。 Redis作為緩存,mysql的數(shù)據(jù)如何與redis進(jìn)行同步呢?(雙寫一致性) 1.我們當(dāng)時(shí)做排行榜業(yè)務(wù)時(shí),把歷史榜單數(shù)據(jù)存儲(chǔ)到了緩存中。這個(gè)雖然也是熱點(diǎn)數(shù)據(jù),但是實(shí)時(shí)要求性不高。

    2024年02月16日
    瀏覽(21)
  • 如何保證數(shù)據(jù)庫和緩存雙寫一致性?

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

    如何保證數(shù)據(jù)庫和緩存雙寫一致性,是面試中經(jīng)常被問的一個(gè)技術(shù)問題,程序汪推薦大家有必要好好研究一波 數(shù)據(jù)庫和緩存(比如:redis)雙寫數(shù)據(jù)一致性問題,是一個(gè)跟開發(fā)語言無關(guān)的公共問題。尤其在高并發(fā)的場景下,這個(gè)問題變得更加嚴(yán)重。 我很負(fù)責(zé)的告訴大家,該問

    2024年01月18日
    瀏覽(40)
  • Redis(十四)雙寫一致性工程案例

    Redis(十四)雙寫一致性工程案例

    https://github.com/alibaba/canal 數(shù)據(jù)庫鏡像 數(shù)據(jù)庫實(shí)時(shí)備份 索引構(gòu)建和實(shí)時(shí)維護(hù)(拆分異構(gòu)索引、倒排索引等) 業(yè)務(wù) cache 刷新 帶業(yè)務(wù)邏輯的增量數(shù)據(jù)處理 傳統(tǒng)mysql主從復(fù)制原理 MySQL的主從復(fù)制將經(jīng)過如下步驟: 當(dāng) master 主服務(wù)器上的數(shù)據(jù)發(fā)生改變時(shí),則將其改變寫入二進(jìn)制事件日志

    2024年02月21日
    瀏覽(22)
  • Redis與MySQL雙寫一致性如何保證

    Redis與MySQL雙寫一致性如何保證

    前言 在分布式系統(tǒng)中,數(shù)據(jù)一致性是一個(gè)重要的問題。當(dāng)我們使用Redis和MySQL這兩種不同的數(shù)據(jù)庫時(shí),如何保證它們之間的雙寫一致性是一個(gè)需要解決的難題。本文將探討Redis與MySQL雙寫一致性的保證方法。 什么是雙寫一致性? 指的是當(dāng)我們更新了數(shù)據(jù)庫的數(shù)據(jù)之后redis中的數(shù)

    2024年02月09日
    瀏覽(28)
  • 如何保證緩存與數(shù)據(jù)庫雙寫時(shí)的數(shù)據(jù)一致性?

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

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

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

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

    2023年04月19日
    瀏覽(35)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包