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

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

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

前言

如何保證數(shù)據(jù)庫和緩存雙寫一致性,是面試中經(jīng)常被問的一個(gè)技術(shù)問題,程序汪推薦大家有必要好好研究一波

數(shù)據(jù)庫和緩存(比如:redis)雙寫數(shù)據(jù)一致性問題,是一個(gè)跟開發(fā)語言無關(guān)的公共問題。尤其在高并發(fā)的場(chǎng)景下,這個(gè)問題變得更加嚴(yán)重。

我很負(fù)責(zé)的告訴大家,該問題無論在面試,還是工作中遇到的概率非常大,所以非常有必要跟大家一起探討一下。

今天這篇文章我會(huì)從淺入深,跟大家一起聊聊,數(shù)據(jù)庫和緩存雙寫數(shù)據(jù)一致性問題常見的解決方案,這些方案中可能存在的坑,以及最優(yōu)方案是什么。

1. 常見方案

通常情況下,我們使用緩存的主要目的是為了提升查詢的性能。大多數(shù)情況下,我們是這樣使用緩存的:

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

  1. 用戶請(qǐng)求過來之后,先查緩存有沒有數(shù)據(jù),如果有則直接返回。

  2. 如果緩存沒數(shù)據(jù),再繼續(xù)查數(shù)據(jù)庫。

  3. 如果數(shù)據(jù)庫有數(shù)據(jù),則將查詢出來的數(shù)據(jù),放入緩存中,然后返回該數(shù)據(jù)。

  4. 如果數(shù)據(jù)庫也沒數(shù)據(jù),則直接返回空。

這是緩存非常常見的用法。一眼看上去,好像沒有啥問題。

但你忽略了一個(gè)非常重要的細(xì)節(jié):如果數(shù)據(jù)庫中的某條數(shù)據(jù),放入緩存之后,又立馬被更新了,那么該如何更新緩存呢?

不更新緩存行不行?

答:當(dāng)然不行,如果不更新緩存,在很長(zhǎng)的一段時(shí)間內(nèi)(決定于緩存的過期時(shí)間),用戶請(qǐng)求從緩存中獲取到的都可能是舊值,而非數(shù)據(jù)庫的最新值。這不是有數(shù)據(jù)不一致的問題?

那么,我們?cè)撊绾胃戮彺婺兀?/p>

目前有以下4種方案:

  1. 先寫緩存,再寫數(shù)據(jù)庫

  2. 先寫數(shù)據(jù)庫,再寫緩存

  3. 先刪緩存,再寫數(shù)據(jù)庫

  4. 先寫數(shù)據(jù)庫,再刪緩存

接下來,我們?cè)敿?xì)說說這4種方案。

2. 先寫緩存,再寫數(shù)據(jù)庫

對(duì)于更新緩存的方案,很多人第一個(gè)想到的可能是在寫操作中直接更新緩存(寫緩存),更直接明了。

那么,問題來了:在寫操作中,到底是先寫緩存,還是先寫數(shù)據(jù)庫呢?

我們?cè)谶@里先聊聊先寫緩存,再寫數(shù)據(jù)庫的情況,因?yàn)樗膯栴}最嚴(yán)重。

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

某一個(gè)用戶的每一次寫操作,如果剛寫完緩存,突然網(wǎng)絡(luò)出現(xiàn)了異常,導(dǎo)致寫數(shù)據(jù)庫失敗了。

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

其結(jié)果是緩存更新成了最新數(shù)據(jù),但數(shù)據(jù)庫沒有,這樣緩存中的數(shù)據(jù)不就變成臟數(shù)據(jù)了?如果此時(shí)該用戶的查詢請(qǐng)求,正好讀取到該數(shù)據(jù),就會(huì)出現(xiàn)問題,因?yàn)樵摂?shù)據(jù)在數(shù)據(jù)庫中根本不存在,這個(gè)問題非常嚴(yán)重。

我們都知道,緩存的主要目的是把數(shù)據(jù)庫的數(shù)據(jù)臨時(shí)保存在內(nèi)存,便于后續(xù)的查詢,提升查詢速度。

但如果某條數(shù)據(jù),在數(shù)據(jù)庫中都不存在,你緩存這種“假數(shù)據(jù)”又有啥意義呢?

因此,先寫緩存,再寫數(shù)據(jù)庫的方案是不可取的,在實(shí)際工作中用得不多。

3. 先寫數(shù)據(jù)庫,再寫緩存

既然上面的方案行不通,接下來,聊聊先寫數(shù)據(jù)庫,再寫緩存的方案,該方案在低并發(fā)編程中有人在用(我猜的)。

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

用戶的寫操作,先寫數(shù)據(jù)庫,再寫緩存,可以避免之前“假數(shù)據(jù)”的問題。但它卻帶來了新的問題。

什么問題呢?

3.1 寫緩存失敗了

如果把寫數(shù)據(jù)庫和寫緩存操作,放在同一個(gè)事務(wù)當(dāng)中,當(dāng)寫緩存失敗了,我們可以把寫入數(shù)據(jù)庫的數(shù)據(jù)進(jìn)行回滾。

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

如果是并發(fā)量比較小,對(duì)接口性能要求不太高的系統(tǒng),可以這么玩。

但如果在高并發(fā)的業(yè)務(wù)場(chǎng)景中,寫數(shù)據(jù)庫和寫緩存,都屬于遠(yuǎn)程操作。為了防止出現(xiàn)大事務(wù),造成的死鎖問題,通常建議寫數(shù)據(jù)庫和寫緩存不要放在同一個(gè)事務(wù)中。

也就是說在該方案中,如果寫數(shù)據(jù)庫成功了,但寫緩存失敗了,數(shù)據(jù)庫中已寫入的數(shù)據(jù)不會(huì)回滾。

這就會(huì)出現(xiàn):數(shù)據(jù)庫是新數(shù)據(jù),而緩存是舊數(shù)據(jù),兩邊數(shù)據(jù)不一致的情況。

3.1 高并發(fā)下的問題

假設(shè)在高并發(fā)的場(chǎng)景中,針對(duì)同一個(gè)用戶的同一條數(shù)據(jù),有兩個(gè)寫數(shù)據(jù)請(qǐng)求:a和b,它們同時(shí)請(qǐng)求到業(yè)務(wù)系統(tǒng)。

其中請(qǐng)求a獲取的是舊數(shù)據(jù),而請(qǐng)求b獲取的是新數(shù)據(jù),如下圖所示:

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

  1. 請(qǐng)求a先過來,剛寫完了數(shù)據(jù)庫。但由于網(wǎng)絡(luò)原因,卡頓了一下,還沒來得及寫緩存。

  2. 這時(shí)候請(qǐng)求b過來了,先寫了數(shù)據(jù)庫。

  3. 接下來,請(qǐng)求b順利寫了緩存。

  4. 此時(shí),請(qǐng)求a卡頓結(jié)束,也寫了緩存。

很顯然,在這個(gè)過程當(dāng)中,請(qǐng)求b在緩存中的新數(shù)據(jù),被請(qǐng)求a的舊數(shù)據(jù)覆蓋了。

也就是說:在高并發(fā)場(chǎng)景中,如果多個(gè)線程同時(shí)執(zhí)行先寫數(shù)據(jù)庫,再寫緩存的操作,可能會(huì)出現(xiàn)數(shù)據(jù)庫是新值,而緩存中是舊值,兩邊數(shù)據(jù)不一致的情況。

3.2 浪費(fèi)系統(tǒng)資源

該方案還有一個(gè)比較大的問題就是:每個(gè)寫操作,寫完數(shù)據(jù)庫,會(huì)馬上寫緩存,比較浪費(fèi)系統(tǒng)資源

為什么這么說呢?

你可以試想一下,如果寫的緩存,并不是簡(jiǎn)單的數(shù)據(jù)內(nèi)容,而是要經(jīng)過非常復(fù)雜的計(jì)算得出的最終結(jié)果。這樣每寫一次緩存,都需要經(jīng)過一次非常復(fù)雜的計(jì)算,不是非常浪費(fèi)系統(tǒng)資源嗎?

尤其是cpu內(nèi)存資源。

還有些業(yè)務(wù)場(chǎng)景比較特殊:寫多讀少。

如果在這類業(yè)務(wù)場(chǎng)景中,每個(gè)用的寫操作,都需要寫一次緩存,有點(diǎn)得不償失。

由此可見,在高并發(fā)的場(chǎng)景中,先寫數(shù)據(jù)庫,再寫緩存,這套方案問題挺多的,也不太建議使用。

如果你已經(jīng)用了,趕緊看看踩坑了沒?

4. 先刪緩存,再寫數(shù)據(jù)庫

通過上面的內(nèi)容我們得知,如果直接更新緩存的問題很多。

那么,為何我們不能換一種思路:不去直接更新緩存,而改為刪除緩存呢?

刪除緩存方案,同樣有兩種:

  1. 先刪緩存,再寫數(shù)據(jù)庫

  2. 先寫數(shù)據(jù)庫,再刪緩存

我們一起先看看:先刪緩存,再寫數(shù)據(jù)庫的情況。

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

說白了,在用戶的寫操作中,先執(zhí)行刪除緩存操作,再去寫數(shù)據(jù)庫。這套方案,可以是可以,但也會(huì)有一樣問題。

4.1 高并發(fā)下的問題

假設(shè)在高并發(fā)的場(chǎng)景中,同一個(gè)用戶的同一條數(shù)據(jù),有一個(gè)讀數(shù)據(jù)請(qǐng)求c,還有另一個(gè)寫數(shù)據(jù)請(qǐng)求d(一個(gè)更新操作),同時(shí)請(qǐng)求到業(yè)務(wù)系統(tǒng)。如下圖所示:

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

  1. 請(qǐng)求d先過來,把緩存刪除了。但由于網(wǎng)絡(luò)原因,卡頓了一下,還沒來得及寫數(shù)據(jù)庫。

  2. 這時(shí)請(qǐng)求c過來了,先查緩存發(fā)現(xiàn)沒數(shù)據(jù),再查數(shù)據(jù)庫,有數(shù)據(jù),但是舊值。

  3. 請(qǐng)求c將數(shù)據(jù)庫中的舊值,更新到緩存中。

  4. 此時(shí),請(qǐng)求d卡頓結(jié)束,把新值寫入數(shù)據(jù)庫。

在這個(gè)過程當(dāng)中,請(qǐng)求d的新值并沒有被請(qǐng)求c寫入緩存,同樣會(huì)導(dǎo)致緩存和數(shù)據(jù)庫的數(shù)據(jù)不一致的情況。更正:圖中步驟7寫入舊值,步驟9要?jiǎng)h掉。

那么,這種場(chǎng)景的數(shù)據(jù)不一致問題,能否解決呢?

4.2 緩存雙刪

在上面的業(yè)務(wù)場(chǎng)景中,一個(gè)讀數(shù)據(jù)請(qǐng)求,一個(gè)寫數(shù)據(jù)請(qǐng)求。當(dāng)寫數(shù)據(jù)請(qǐng)求把緩存刪了之后,讀數(shù)據(jù)請(qǐng)求,可能把當(dāng)時(shí)從數(shù)據(jù)庫查詢出來的舊值,寫入緩存當(dāng)中。

有人說還不好辦,請(qǐng)求d在寫完數(shù)據(jù)庫之后,把緩存重新刪一次不就行了?

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

這就是我們所說的緩存雙刪,即在寫數(shù)據(jù)庫之前刪除一次,寫完數(shù)據(jù)庫后,再刪除一次。

該方案有個(gè)非常關(guān)鍵的地方是:第二次刪除緩存,并非立馬就刪,而是要在一定的時(shí)間間隔之后。

我們?cè)僦匦禄仡櫼幌?,高并發(fā)下一個(gè)讀數(shù)據(jù)請(qǐng)求,一個(gè)寫數(shù)據(jù)請(qǐng)求導(dǎo)致數(shù)據(jù)不一致的產(chǎn)生過程:

  1. 請(qǐng)求d先過來,把緩存刪除了。但由于網(wǎng)絡(luò)原因,卡頓了一下,還沒來得及寫數(shù)據(jù)庫。

  2. 這時(shí)請(qǐng)求c過來了,先查緩存發(fā)現(xiàn)沒數(shù)據(jù),再查數(shù)據(jù)庫,有數(shù)據(jù),但是舊值。

  3. 請(qǐng)求c將數(shù)據(jù)庫中的舊值,更新到緩存中。

  4. 此時(shí),請(qǐng)求d卡頓結(jié)束,把新值寫入數(shù)據(jù)庫。

  5. 一段時(shí)間之后,比如:500ms,請(qǐng)求d將緩存刪除。

這樣來看確實(shí)可以解決緩存不一致問題。

那么,為什么一定要間隔一段時(shí)間之后,才能刪除緩存呢?

請(qǐng)求d卡頓結(jié)束,把新值寫入數(shù)據(jù)庫后,請(qǐng)求c將數(shù)據(jù)庫中的舊值,更新到緩存中。

此時(shí),如果請(qǐng)求d刪除太快,在請(qǐng)求c將數(shù)據(jù)庫中的舊值更新到緩存之前,就已經(jīng)把緩存刪除了,這次刪除就沒任何意義。必須要在請(qǐng)求c更新緩存之后,再刪除緩存,才能把舊值及時(shí)刪除了。

所以需要在請(qǐng)求d中加一個(gè)時(shí)間間隔,確保請(qǐng)求c,或者類似于請(qǐng)求c的其他請(qǐng)求,如果在緩存中設(shè)置了舊值,最終都能夠被請(qǐng)求d刪除掉。

接下來,還有一個(gè)問題:如果第二次刪除緩存時(shí),刪除失敗了該怎么辦?

這里先留點(diǎn)懸念,后面會(huì)詳細(xì)說。

5. 先寫數(shù)據(jù)庫,再刪緩存

從前面得知,先刪緩存,再寫數(shù)據(jù)庫,在并發(fā)的情況下,也可能會(huì)出現(xiàn)緩存和數(shù)據(jù)庫的數(shù)據(jù)不一致的情況。

那么,我們只能寄希望于最后的方案了。

接下來,我們重點(diǎn)看看先寫數(shù)據(jù)庫,再刪緩存的方案。

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

在高并發(fā)的場(chǎng)景中,有一個(gè)讀數(shù)據(jù)請(qǐng)求,有一個(gè)寫數(shù)據(jù)請(qǐng)求,更新過程如下:

  1. 請(qǐng)求e先寫數(shù)據(jù)庫,由于網(wǎng)絡(luò)原因卡頓了一下,沒有來得及刪除緩存。

  2. 請(qǐng)求f查詢緩存,發(fā)現(xiàn)緩存中有數(shù)據(jù),直接返回該數(shù)據(jù)。

  3. 請(qǐng)求e刪除緩存。

在這個(gè)過程中,只有請(qǐng)求f讀了一次舊數(shù)據(jù),后來舊數(shù)據(jù)被請(qǐng)求e及時(shí)刪除了,看起來問題不大。

但如果是讀數(shù)據(jù)請(qǐng)求先過來呢?

  1. 請(qǐng)求f查詢緩存,發(fā)現(xiàn)緩存中有數(shù)據(jù),直接返回該數(shù)據(jù)。

  2. 請(qǐng)求e先寫數(shù)據(jù)庫。

  3. 請(qǐng)求e刪除緩存。

這種情況看起來也沒問題呀?

答:對(duì)的。

但就怕出現(xiàn)下面這種情況,即緩存自己失效了。如下圖所示:

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

  1. 緩存過期時(shí)間到了,自動(dòng)失效。

  2. 請(qǐng)求f查詢緩存,發(fā)緩存中沒有數(shù)據(jù),查詢數(shù)據(jù)庫的舊值,但由于網(wǎng)絡(luò)原因卡頓了,沒有來得及更新緩存。

  3. 請(qǐng)求e先寫數(shù)據(jù)庫,接著刪除了緩存。

  4. 請(qǐng)求f更新舊值到緩存中。

這時(shí),緩存和數(shù)據(jù)庫的數(shù)據(jù)同樣出現(xiàn)不一致的情況了。

但這種情況還是比較少的,需要同時(shí)滿足以下條件才可以:

  1. 緩存剛好自動(dòng)失效。

  2. 請(qǐng)求f從數(shù)據(jù)庫查出舊值,更新緩存的耗時(shí),比請(qǐng)求e寫數(shù)據(jù)庫,并且刪除緩存的還長(zhǎng)。

我們都知道查詢數(shù)據(jù)庫的速度,一般比寫數(shù)據(jù)庫要快,更何況寫完數(shù)據(jù)庫,還要?jiǎng)h除緩存。所以絕大多數(shù)情況下,寫數(shù)據(jù)請(qǐng)求比讀數(shù)據(jù)情況耗時(shí)更長(zhǎng)。

由此可見,系統(tǒng)同時(shí)滿足上述兩個(gè)條件的概率非常小。

推薦大家使用先寫數(shù)據(jù)庫,再刪緩存的方案,雖說不能100%避免數(shù)據(jù)不一致問題,但出現(xiàn)該問題的概率,相對(duì)于其他方案來說是最小的。

但在該方案中,如果刪除緩存失敗了該怎么辦呢?

6. 刪緩存失敗怎么辦?

其實(shí)先寫數(shù)據(jù)庫,再刪緩存的方案,跟緩存雙刪的方案一樣,有一個(gè)共同的風(fēng)險(xiǎn)點(diǎn),即:如果緩存刪除失敗了,也會(huì)導(dǎo)致緩存和數(shù)據(jù)庫的數(shù)據(jù)不一致。

那么,刪除緩存失敗怎么辦呢?

答:需要加重試機(jī)制。

在接口中如果更新了數(shù)據(jù)庫成功了,但更新緩存失敗了,可以立刻重試3次。如果其中有任何一次成功,則直接返回成功。如果3次都失敗了,則寫入數(shù)據(jù)庫,準(zhǔn)備后續(xù)再處理。

當(dāng)然,如果你在接口中直接同步重試,該接口并發(fā)量比較高的時(shí)候,可能有點(diǎn)影響接口性能。

這時(shí),就需要改成異步重試了。

異步重試方式有很多種,比如:

  1. 每次都單獨(dú)起一個(gè)線程,該線程專門做重試的工作。但如果在高并發(fā)的場(chǎng)景下,可能會(huì)創(chuàng)建太多的線程,導(dǎo)致系統(tǒng)OOM問題,不太建議使用。

  2. 將重試的任務(wù)交給線程池處理,但如果服務(wù)器重啟,部分?jǐn)?shù)據(jù)可能會(huì)丟失。

  3. 將重試數(shù)據(jù)寫表,然后使用elastic-job等定時(shí)任務(wù)進(jìn)行重試。

  4. 將重試的請(qǐng)求寫入mq等消息中間件中,在mq的consumer中處理。

  5. 訂閱mysql的binlog,在訂閱者中,如果發(fā)現(xiàn)了更新數(shù)據(jù)請(qǐng)求,則刪除相應(yīng)的緩存。

7. 定時(shí)任務(wù)

使用定時(shí)任務(wù)重試的具體方案如下:

  1. 當(dāng)用戶操作寫完數(shù)據(jù)庫,但刪除緩存失敗了,需要將用戶數(shù)據(jù)寫入重試表中。如下圖所示:

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

  2. 在定時(shí)任務(wù)中,異步讀取重試表中的用戶數(shù)據(jù)。重試表需要記錄一個(gè)重試次數(shù)字段,初始值為0。然后重試5次,不斷刪除緩存,每重試一次該字段值+1。如果其中有任意一次成功了,則返回成功。如果重試了5次,還是失敗,則我們需要在重試表中記錄一個(gè)失敗的狀態(tài),等待后續(xù)進(jìn)一步處理。

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

  3. 在高并發(fā)場(chǎng)景中,定時(shí)任務(wù)推薦使用elastic-job。相對(duì)于xxl-job等定時(shí)任務(wù),它可以分片處理,提升處理速度。同時(shí)每片的間隔可以設(shè)置成:1,2,3,5,7秒等。

如果大家對(duì)定時(shí)任務(wù)比較感興趣的話,可以看看我的另一篇文章《學(xué)會(huì)這10種定時(shí)任務(wù),我有點(diǎn)飄了》,里面列出了目前最主流的定時(shí)任務(wù)。

使用定時(shí)任務(wù)重試的話,有個(gè)缺點(diǎn)就是實(shí)時(shí)性沒那么高,對(duì)于實(shí)時(shí)性要求特別高的業(yè)務(wù)場(chǎng)景,該方案不太適用。但是對(duì)于一般場(chǎng)景,還是可以用一用的。

但它有一個(gè)很大的優(yōu)點(diǎn),即數(shù)據(jù)是落庫的,不會(huì)丟數(shù)據(jù)。

8. mq

在高并發(fā)的業(yè)務(wù)場(chǎng)景中,mq(消息隊(duì)列)是必不可少的技術(shù)之一。它不僅可以異步解耦,還能削峰填谷。對(duì)保證系統(tǒng)的穩(wěn)定性是非常有意義的。

mq的生產(chǎn)者,生產(chǎn)了消息之后,通過指定的topic發(fā)送到mq服務(wù)器。然后mq的消費(fèi)者,訂閱該topic的消息,讀取消息數(shù)據(jù)之后,做業(yè)務(wù)邏輯處理。

使用mq重試的具體方案如下:

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

  1. 當(dāng)用戶操作寫完數(shù)據(jù)庫,但刪除緩存失敗了,產(chǎn)生一條mq消息,發(fā)送給mq服務(wù)器。

  2. mq消費(fèi)者讀取mq消息,重試5次刪除緩存。如果其中有任意一次成功了,則返回成功。如果重試了5次,還是失敗,則寫入死信隊(duì)列中。

  3. 推薦mq使用rocketmq,重試機(jī)制和死信隊(duì)列默認(rèn)是支持的。使用起來非常方便,而且還支持順序消息,延遲消息和事務(wù)消息等多種業(yè)務(wù)場(chǎng)景。

當(dāng)然在該方案中,刪除緩存可以完全走異步。即用戶的寫操作,在寫完數(shù)據(jù)庫之后,不用立刻刪除一次緩存。而直接發(fā)送mq消息,到mq服務(wù)器,然后有mq消費(fèi)者全權(quán)負(fù)責(zé)刪除緩存的任務(wù)。

因?yàn)閙q的實(shí)時(shí)性還是比較高的,因此改良后的方案也是一種不錯(cuò)的選擇。

9. binlog

前面我們聊過的,無論是定時(shí)任務(wù),還是mq(消息隊(duì)列),做重試機(jī)制,對(duì)業(yè)務(wù)都有一定的侵入性。

在使用定時(shí)任務(wù)的方案中,需要在業(yè)務(wù)代碼中增加額外邏輯,如果刪除緩存失敗,需要將數(shù)據(jù)寫入重試表。

而使用mq的方案中,如果刪除緩存失敗了,需要在業(yè)務(wù)代碼中發(fā)送mq消息到mq服務(wù)器。

其實(shí),還有一種更優(yōu)雅的實(shí)現(xiàn),即監(jiān)聽binlog,比如使用:canal等中間件。

具體方案如下:

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

  1. 在業(yè)務(wù)接口中寫數(shù)據(jù)庫之后,就不管了,直接返回成功。

  2. mysql服務(wù)器會(huì)自動(dòng)把變更的數(shù)據(jù)寫入binlog中。

  3. binlog訂閱者獲取變更的數(shù)據(jù),然后刪除緩存。

這套方案中業(yè)務(wù)接口確實(shí)簡(jiǎn)化了一些流程,只用關(guān)心數(shù)據(jù)庫操作即可,而在binlog訂閱者中做緩存刪除工作。

但如果只是按照?qǐng)D中的方案進(jìn)行刪除緩存,只刪除了一次,也可能會(huì)失敗。

如何解決這個(gè)問題呢?

答:這就需要加上前面聊過的重試機(jī)制了。如果刪除緩存失敗,寫入重試表,使用定時(shí)任務(wù)重試?;蛘邔懭雖q,讓mq自動(dòng)重試。

在這里推薦使用mq自動(dòng)重試機(jī)制。

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

在binlog訂閱者中如果刪除緩存失敗,則發(fā)送一條mq消息到mq服務(wù)器,在mq消費(fèi)者中自動(dòng)重試5次。如果有任意一次成功,則直接返回成功。如果重試5次后還是失敗,則該消息自動(dòng)被放入死信隊(duì)列,后面可能需要人工介入。文章來源地址http://www.zghlxwxcb.cn/news/detail-799410.html

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

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

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

相關(guān)文章

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

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

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

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

    2024年02月14日
    瀏覽(23)
  • Redis緩存MySQL數(shù)據(jù)庫存儲(chǔ)二者如何保證數(shù)據(jù)一致性

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

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

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

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

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

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

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

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

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

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

    2023年04月19日
    瀏覽(35)
  • 分布式系統(tǒng)中數(shù)據(jù)庫和緩存雙寫一致性的實(shí)現(xiàn)技術(shù)

    標(biāo)題:分布式系統(tǒng)中數(shù)據(jù)庫和緩存雙寫一致性的實(shí)現(xiàn)技術(shù) 在分布式系統(tǒng)中,為了確保數(shù)據(jù)庫和緩存之間的數(shù)據(jù)一致性,雙寫一致性成為了一個(gè)關(guān)鍵的挑戰(zhàn)。本文將深入探討如何利用一些常見的技術(shù)手段來保證數(shù)據(jù)庫和緩存的雙寫一致性,以及通過舉例說明這些技術(shù)是如何在實(shí)

    2024年01月16日
    瀏覽(85)
  • 怎么保證緩存與數(shù)據(jù)庫的最終一致性?

    怎么保證緩存與數(shù)據(jù)庫的最終一致性?

    目錄 零.讀數(shù)據(jù)的標(biāo)準(zhǔn)操作 一.Cache aside Patten--旁路模式 二.Read/Write Through Pattern--讀寫穿透 三.Write Back?Pattern--寫回 四.運(yùn)用canal監(jiān)聽mysql的binlog實(shí)現(xiàn)緩存同步 這里想說的是不管哪種模式讀操作都是一樣的,這是一種統(tǒng)一的規(guī)范: 但寫操作和同步策略卻有不同。 這個(gè)是最常見的

    2024年04月08日
    瀏覽(26)
  • 如何保證ES和數(shù)據(jù)庫的數(shù)據(jù)一致性?

    如何保證ES和數(shù)據(jù)庫的數(shù)據(jù)一致性?

    在業(yè)務(wù)中,我們通常需要把數(shù)據(jù)庫中的數(shù)據(jù)變更同步到ES中,那么如何保證數(shù)據(jù)庫和ES的一致性呢?通常有以下幾種做法: 雙寫 在代碼中,對(duì)數(shù)據(jù)庫和ES進(jìn)行雙寫,并且先操作本地?cái)?shù)據(jù)庫,后操作ES,而且還需要把兩個(gè)操作放到一個(gè)事務(wù)中: ?在以上邏輯中,如果寫數(shù)據(jù)庫成功

    2024年04月28日
    瀏覽(22)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包