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

如何解決緩存數(shù)據(jù)不一致性問(wèn)題

 更新時(shí)間:2025年01月10日 09:29:28   作者:Wchisper  
文章主要討論了緩存和數(shù)據(jù)庫(kù)數(shù)據(jù)一致性的問(wèn)題,包括數(shù)據(jù)不一致的原因、查詢(xún)和更新數(shù)據(jù)的邏輯、緩存雙刪方案以及優(yōu)化建議

1. 數(shù)據(jù)不一致的原因

1.1 雙寫(xiě)導(dǎo)致數(shù)據(jù)不一致

由于分布性系統(tǒng),不能保證每個(gè)節(jié)點(diǎn)都可用,所有可能引起 Redis 在極限情況下數(shù)據(jù)沒(méi)有寫(xiě)入成功,那么此時(shí)緩存中的數(shù)據(jù)和數(shù)據(jù)庫(kù)數(shù)據(jù)不一致。

數(shù)據(jù)的更新為什么會(huì)成功:因?yàn)槭聞?wù)保證數(shù)據(jù)不管是成功還是失敗,都不會(huì)有臟數(shù)據(jù)。

1.2 高并發(fā)導(dǎo)致數(shù)據(jù)不一致

數(shù)據(jù)在修改的過(guò)程中必定會(huì)存在網(wǎng)絡(luò)延時(shí),因?yàn)榉植际较到y(tǒng)節(jié)點(diǎn)相互獨(dú)立部署,那么在并發(fā)讀的情況之下,還沒(méi)來(lái)得及修改完,那么對(duì)于讀操作,讀到的數(shù)據(jù)都是老的數(shù)據(jù)

如果是某些不嚴(yán)謹(jǐn)?shù)那闆r,無(wú)所謂,如果是極致的嚴(yán)謹(jǐn),那么就不能這么做了。比如我們的環(huán)境監(jiān)測(cè),大氣的一些數(shù)據(jù)會(huì)每隔1-2分鐘更新,甚至有的是5分鐘更新,所以如果讀到的是一些老的數(shù)據(jù),是沒(méi)有關(guān)系的,因?yàn)樽罱K幾秒或者幾十秒以后會(huì)更新,這些數(shù)據(jù)的來(lái)去不會(huì)很大,而且我們能容忍一定的誤差,所以也就無(wú)所謂了。

2. 查詢(xún)數(shù)據(jù)的邏輯

先請(qǐng)求先到 Redis,如果命中則返回結(jié)果。如果 Redis 中沒(méi)有數(shù)據(jù),則從數(shù)據(jù)庫(kù)查詢(xún),再寫(xiě)入到緩存中,再返回結(jié)果。

3. 更新數(shù)據(jù)的邏輯

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

3.1.1 方案一

在并發(fā)不高的情況下:先刪除 Redis 中的舊數(shù)據(jù)。更新數(shù)據(jù)庫(kù)中的數(shù)據(jù)。再將數(shù)據(jù)庫(kù)中的數(shù)據(jù)同步到 Redis 中。

3.1.2 方案二

在高并發(fā)的情況下,假設(shè)有請(qǐng)求 A 進(jìn)行更新操作,另一個(gè)請(qǐng)求 B 進(jìn)行查詢(xún)操作,那么有可能會(huì)出現(xiàn):

  1. A 進(jìn)行更新操作前,先刪除了緩存
  2. B 查詢(xún)發(fā)現(xiàn)緩存不存在
  3. B 查詢(xún)數(shù)據(jù)庫(kù)的舊值
  4. B 將舊值寫(xiě)入到緩存
  5. A 執(zhí)行更新,將新值寫(xiě)入到數(shù)據(jù)庫(kù)
  6. 后續(xù)的請(qǐng)求因?yàn)榘l(fā)現(xiàn)緩存中有數(shù)據(jù),導(dǎo)致 A 更新的數(shù)據(jù)一直無(wú)法更新到緩存中,這樣便出現(xiàn)了數(shù)據(jù)庫(kù)與緩存不一致的情況。

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

3.2.1 方案一

該方案雖然存在并發(fā)問(wèn)題,但是出現(xiàn)上述情況的概率是極低的,也有一些企業(yè)在使用這種方案。

在超高并發(fā)下,請(qǐng)求 A 執(zhí)行更新操作,請(qǐng)求 B 進(jìn)行查詢(xún)操作:

  1. B 將新值寫(xiě)入到數(shù)據(jù)庫(kù)
  2. A 查詢(xún) Redis 得到舊數(shù)據(jù)
  3. 線程 B 刪除緩存
  4. 這樣就會(huì)導(dǎo)致 A 修改數(shù)據(jù) —> A 刪除 Redis 之間出現(xiàn)臟數(shù)據(jù)。

3.2.2 方案二

在超高并發(fā)下,請(qǐng)求 A 執(zhí)行更新操作,請(qǐng)求 B 進(jìn)行查詢(xún)操作:

  1. 緩存剛好失效
  2. B 查詢(xún)數(shù)據(jù)庫(kù),得到一個(gè)舊值
  3. A 將新值寫(xiě)入到數(shù)據(jù)庫(kù)
  4. 線程 A 刪除緩存
  5. B 將舊值寫(xiě)入到緩存
  6. 這樣就會(huì)導(dǎo)致后續(xù)的請(qǐng)求之間出現(xiàn)臟數(shù)據(jù)。

3.3 緩存雙刪方案

它的流程為:

  1. 先刪除緩存
  2. 再寫(xiě)數(shù)據(jù)庫(kù)
  3. 休眠一段時(shí)間,再刪除緩存

回顧一下方案“先刪除緩存,再更新數(shù)據(jù)庫(kù)”可能造成數(shù)據(jù)庫(kù)與緩存不一致的情況。

假設(shè)有請(qǐng)求 A 進(jìn)行更新操作,另一個(gè)請(qǐng)求 B 進(jìn)行查詢(xún)操作,如果使用緩存雙刪策略:

  1. A 進(jìn)行更新操作前,先刪除了緩存
  2. B 查詢(xún)發(fā)現(xiàn)緩存不存在
  3. B 查詢(xún)數(shù)據(jù)庫(kù)的舊值
  4. B 將舊值寫(xiě)入到緩存
  5. A 執(zhí)行更新,將新值寫(xiě)入到數(shù)據(jù)庫(kù),執(zhí)行休眠 Thread.sleep(t)
  6. A 蘇醒,再次將緩存中的值刪除

緩存雙刪的優(yōu)點(diǎn)是大大降低了數(shù)據(jù)庫(kù)與緩存不一致的概率的發(fā)生,注意這里只是降低,并不是說(shuō)完全的避免,途中紅框的地方就是緩存臟數(shù)據(jù)的時(shí)間,缺點(diǎn)為一定程度上降低了吞吐量,因?yàn)橄到y(tǒng)進(jìn)行了休眠

這里為什么要采用休眠,對(duì)數(shù)據(jù)進(jìn)行延遲緩存,原因是

  1. 例如:如果在 A 刪除緩存之后,數(shù)據(jù)庫(kù)修改之間 C 再次請(qǐng)求數(shù)據(jù)庫(kù),將老的信息存儲(chǔ)進(jìn)緩存,那么后續(xù)所有的請(qǐng)求打在緩存中,還是獲取到老的數(shù)據(jù)
  2. 在分庫(kù)分表的情況下,延遲一定的時(shí)間,也保證了,修改后的數(shù)據(jù)全部同步到所有的數(shù)據(jù)庫(kù)中。

4. 擴(kuò)展:其它的解決雙寫(xiě)一直問(wèn)題

通過(guò)監(jiān)聽(tīng)數(shù)據(jù)庫(kù)日志,來(lái)修改 Redis 的數(shù)據(jù),使數(shù)據(jù)的修改達(dá)到準(zhǔn)實(shí)時(shí)的級(jí)別,例如:canal。但是這種情況下會(huì)有一些時(shí)間的延遲,也會(huì)短暫的產(chǎn)生臟數(shù)據(jù)。這種情況適用于寫(xiě)多讀少的場(chǎng)景

完全使用緩存作為數(shù)據(jù)庫(kù),后面在定時(shí)任務(wù)修改數(shù)據(jù)庫(kù)數(shù)據(jù)。這種情況下,沒(méi)要求對(duì) Redis 的三高要求非常高,可以采用云廠商的 Redis 服務(wù)。

讀取的時(shí)候只提供 Redis,也就是說(shuō),當(dāng)更新操作一開(kāi)始從 Redis 中刪除數(shù)據(jù)了,用戶(hù)去讀 Redis,如果沒(méi)有是不會(huì)從數(shù)據(jù)庫(kù)中讀的,因?yàn)橹惶峁?Redis 的讀取,寫(xiě)入的時(shí)候只在數(shù)據(jù)新增以及更新后才會(huì)放入到 Redis,那么如此一來(lái),并發(fā)讀的時(shí)候就不會(huì)從數(shù)據(jù)庫(kù)讀取老的數(shù)據(jù)并且放入 Redis 中了。沒(méi)有讀到也沒(méi)關(guān)系,做一些空數(shù)據(jù)的處理,可能會(huì)有個(gè)幾百毫秒或者 1-2s 的延遲,但是可以忍受。但是要注意做好緩存穿透的校驗(yàn)處理。

5. 緩存數(shù)據(jù)的思考

我們能放入緩存的數(shù)據(jù)本就不應(yīng)該是實(shí)時(shí)性、一致性要求超高的,所以緩存數(shù)據(jù)的時(shí)候加上過(guò)期時(shí)間,保證每天拿到當(dāng)前最新數(shù)據(jù)即可。

我們不應(yīng)該過(guò)度設(shè)計(jì),增加系統(tǒng)的復(fù)雜性,遇到實(shí)時(shí)性、一致性要求高的數(shù)據(jù),就應(yīng)該查數(shù)據(jù)庫(kù),即使慢點(diǎn)。

超高并發(fā)場(chǎng)景的一致性,都是最終一致性,也就是弱一致性,所以要考慮每一個(gè)環(huán)節(jié)可能失敗的情況,補(bǔ)償 job 也是常有的。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Redis的Spring客戶(hù)端使用小結(jié)

    Redis的Spring客戶(hù)端使用小結(jié)

    在Spring中使用Redis,可以極大地提升應(yīng)用程序的性能和響應(yīng)速度,本文主要介紹了Redis的Spring客戶(hù)端使用小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-04-04
  • redis在spring boot中異常退出的問(wèn)題解決方案

    redis在spring boot中異常退出的問(wèn)題解決方案

    這篇文章主要介紹了redis在spring boot中異常退出的問(wèn)題解決方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2025-05-05
  • Redis權(quán)限和訪問(wèn)控制的實(shí)現(xiàn)示例

    Redis權(quán)限和訪問(wèn)控制的實(shí)現(xiàn)示例

    Redis提供了一些機(jī)制來(lái)保護(hù)敏感數(shù)據(jù)和限制對(duì)Redis服務(wù)器的訪問(wèn),本文主要介紹了Redis權(quán)限和訪問(wèn)控制的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • Redis IP地址的綁定的實(shí)現(xiàn)

    Redis IP地址的綁定的實(shí)現(xiàn)

    這篇文章主要介紹了Redis IP地址的綁定的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 基于Redis實(shí)現(xiàn)API接口訪問(wèn)次數(shù)限制

    基于Redis實(shí)現(xiàn)API接口訪問(wèn)次數(shù)限制

    日常開(kāi)發(fā)中會(huì)有一個(gè)常見(jiàn)的需求,需要限制接口在單位時(shí)間內(nèi)的訪問(wèn)次數(shù),比如說(shuō)某個(gè)免費(fèi)的接口限制單個(gè)IP一分鐘內(nèi)只能訪問(wèn)5次,該怎么實(shí)現(xiàn)呢,本文小編給大家介紹了如何基于Redis實(shí)現(xiàn)API接口訪問(wèn)次數(shù)限制,需要的朋友可以參考下
    2024-11-11
  • Redis不是一直號(hào)稱(chēng)單線程效率也很高嗎,為什么又采用多線程了?

    Redis不是一直號(hào)稱(chēng)單線程效率也很高嗎,為什么又采用多線程了?

    這篇文章主要介紹了Redis不是一直號(hào)稱(chēng)單線程效率也很高嗎,為什么又采用多線程了的相關(guān)資料,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • python腳本實(shí)現(xiàn)Redis未授權(quán)批量提權(quán)

    python腳本實(shí)現(xiàn)Redis未授權(quán)批量提權(quán)

    這篇文章主要給大家介紹了關(guān)于利用python腳本實(shí)現(xiàn)redis未授權(quán)批量提權(quán)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-09-09
  • Redis實(shí)現(xiàn)延遲任務(wù)的常見(jiàn)方案詳解

    Redis實(shí)現(xiàn)延遲任務(wù)的常見(jiàn)方案詳解

    延遲任務(wù)(Delayed?Task)是指在未來(lái)的某個(gè)時(shí)間點(diǎn),執(zhí)行相應(yīng)的任務(wù),本文為大家整理了Redis實(shí)現(xiàn)延遲任務(wù)的幾個(gè)常見(jiàn)方案,希望對(duì)大家有所幫助
    2024-04-04
  • Redis事務(wù)處理的使用操作方法

    Redis事務(wù)處理的使用操作方法

    Redis保證一個(gè)事務(wù)中的所有命令要么都執(zhí)行,要么都不執(zhí)行(原子性),如果客戶(hù)端發(fā)送了EXEC命令,所有的命令就都會(huì)被執(zhí)行,即使此后客戶(hù)端斷線也沒(méi)關(guān)系,因?yàn)镽edis中已經(jīng)記錄了所有要執(zhí)行的命令,下面通過(guò)本文給大家介紹Redis事務(wù)處理的使用操作,感興趣的朋友一起看看吧
    2021-10-10
  • redis慢查詢(xún)?nèi)罩镜脑L問(wèn)和管理方式

    redis慢查詢(xún)?nèi)罩镜脑L問(wèn)和管理方式

    這篇文章主要介紹了redis慢查詢(xún)?nèi)罩镜脑L問(wèn)和管理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12

最新評(píng)論

黔西县| 花垣县| 洛扎县| 奉新县| 临汾市| 鄂伦春自治旗| 嘉黎县| 饶阳县| 湖南省| 淅川县| 泰安市| 绥中县| 榕江县| 甘泉县| 晋城| 芜湖县| 义马市| 富民县| 甘肃省| 岑巩县| 遂平县| 香港 | 东辽县| 安化县| 靖安县| 南乐县| 温州市| 资阳市| 徐汇区| 灵寿县| 石狮市| 乐清市| 新竹县| 舟曲县| 四会市| 三原县| 桐庐县| 延长县| 安阳县| 衡阳县| 和硕县|