吴忠躺衫网络科技有限公司

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

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

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

MySQL與Redis延遲雙刪策略

科技綠洲 ? 來(lái)源:Java技術(shù)指北 ? 作者:Java技術(shù)指北 ? 2023-09-25 14:28 ? 次閱讀

背景

在當(dāng)前環(huán)境下,通常我們會(huì)首選redis緩存來(lái)減輕我們數(shù)據(jù)庫(kù)訪問(wèn)壓力。但是也會(huì)遇到以下這種情況:大量用戶來(lái)訪問(wèn)我們系統(tǒng),首先會(huì)去查詢(xún)緩存, 如果緩存中沒(méi)有數(shù)據(jù),則去查詢(xún)數(shù)據(jù)庫(kù),然后更新數(shù)據(jù)到緩存中,并且如果數(shù)據(jù)庫(kù)中的數(shù)據(jù)發(fā)生了改變則需要同步到redis中,同步過(guò)程中需要保證 MySQL與redis數(shù)據(jù)一致性問(wèn)題,在這個(gè)同步過(guò)程中出現(xiàn)短暫的數(shù)據(jù)延遲也是正常現(xiàn)象,但是最終需要保證mysql與緩存中的一致性。

//我們通常使用redis的邏輯
    //通常我們是先查詢(xún)r(jià)eids
    String value = RedisUtils.get(key);
    if (!StringUtils.isEmpty(value)){
        return value;
    }
//從數(shù)據(jù)庫(kù)中獲取數(shù)據(jù)
    value = getValueForDb(key);
    if (!StringUtils.isEmpty(value)){
           RedisUtils.set(key,value);
        return value;
     }

1、什么是延遲雙刪?

延遲雙刪策略是分布式系統(tǒng)中數(shù)據(jù)庫(kù)存儲(chǔ)和緩存數(shù)據(jù)保持一致性的常用策略,但它不是強(qiáng)一致。其實(shí)不管哪種方案,都避免不了Redis存在臟數(shù)據(jù)的問(wèn)題,只能減輕這個(gè)問(wèn)題,要想徹底解決,得要用到同步鎖和對(duì)應(yīng)的業(yè)務(wù)邏輯層面解決。

2、為什么要進(jìn)行延遲雙刪?

一般我們?cè)诟聰?shù)據(jù)庫(kù)數(shù)據(jù)時(shí),需要同步redis中緩存的數(shù)據(jù) 所以我們一般會(huì)給出兩種方案:

  • 第一種方案:先執(zhí)行update操作,再執(zhí)行緩存清除。
  • 第二種方案:先執(zhí)行緩存清除,再執(zhí)行update操作。

但是這兩種方案在并發(fā)請(qǐng)求中容易出現(xiàn)以下問(wèn)題

圖片

  • 第一種方案弊端:當(dāng)請(qǐng)求1去執(zhí)行數(shù)據(jù)庫(kù)更新操作之后,還沒(méi)執(zhí)行緩存清除時(shí),請(qǐng)求2就進(jìn)來(lái)了查詢(xún)了緩存,此時(shí)緩存中數(shù)據(jù)還是舊數(shù)據(jù),還沒(méi)來(lái)得機(jī)刪除導(dǎo)致數(shù)據(jù)出現(xiàn)問(wèn)題,但是當(dāng)t1執(zhí)行緩存刪除操作之后,后面的請(qǐng)求查詢(xún)不到緩存,再到數(shù)據(jù)中查詢(xún),然后更新到緩存中,這種影響是比較小的
    1. t1線程 先更新db;
    2. t2線程查詢(xún)命中緩存 返回舊的數(shù)據(jù);
    3. 假設(shè)t1線程更新完db,預(yù)計(jì)5毫秒刪除完緩存key 在5毫秒內(nèi) 其他線程查詢(xún)緩存結(jié)果還是為舊的數(shù)據(jù),但是 5毫秒后查詢(xún)緩存結(jié)果是為空,在從新將db最新的結(jié)果同步到Redis中。
    4. 一個(gè)項(xiàng)目中出現(xiàn)延遲是非常正常的,所以該情況發(fā)生的延遲對(duì)業(yè)務(wù)的影響其實(shí)很小。但是如果發(fā)生了,刪除緩存失敗呢?

1.不斷重試----如果是在http協(xié)議接口中 會(huì)導(dǎo)致接口響應(yīng)變慢 調(diào)用該接口 會(huì)發(fā)生響應(yīng)超時(shí) 2.或者通過(guò)mq異步的形式同步

圖片

  • 第二種方案弊端:當(dāng)請(qǐng)求1執(zhí)行清除緩存后,還未執(zhí)行數(shù)據(jù)更新操作的時(shí),請(qǐng)求2進(jìn)來(lái)查詢(xún)到數(shù)據(jù)庫(kù)的舊數(shù)據(jù),并寫(xiě)入了redis,這就導(dǎo)致了數(shù)據(jù)庫(kù)與redis數(shù)據(jù)不一致問(wèn)題。
    1. t1線程先刪除緩存;
    2. t2線程讀取緩存為null,同步db數(shù)據(jù)到緩存中;
    3. t1線程更新db中的數(shù)據(jù);
    4. t3線程查詢(xún)緩存中數(shù)據(jù)是舊數(shù)據(jù);

3、對(duì)于方案處理都有弊端,那么我們需要使用延遲雙刪策略

先進(jìn)行緩存清除,再執(zhí)行update,最后(延遲N秒)再執(zhí)行緩存清除。進(jìn)行兩次刪除,且中間需要延遲一段時(shí)間

RedisUtils.del(key);// 先刪除緩存
    updateDB(user);// 更新db中的數(shù)據(jù)
    Thread.sleep(N);// 延遲一段時(shí)間,在刪除該緩存key
    RedisUtils.del(key);// 先刪除緩存

4、需要注意的點(diǎn)

上述中(延遲N秒)的時(shí)間要大于一次寫(xiě)操作的時(shí)間。原因:如果延遲時(shí)間小于寫(xiě)入redis的時(shí)間,會(huì)導(dǎo)致請(qǐng)求1清除了緩存,但是請(qǐng)求2緩存還未寫(xiě)入的尷尬。。。

5、延遲的時(shí)間如何確定?

在業(yè)務(wù)程序運(yùn)行時(shí),統(tǒng)計(jì)業(yè)務(wù)邏輯執(zhí)行讀數(shù)據(jù)和寫(xiě)緩存的操作時(shí)間,以此為基礎(chǔ)來(lái)進(jìn)行估算。因?yàn)檫@個(gè)方案會(huì)在第一次刪除緩存值后,延遲一段時(shí)間再次進(jìn)行刪除,所以稱(chēng)為“延遲雙刪”。

小結(jié)

延遲雙刪策略只是一種同步數(shù)據(jù)庫(kù)與緩存的手段,在系統(tǒng)并發(fā)量不高的情況下可以使用這種方式解決。

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

    關(guān)注

    13

    文章

    4353

    瀏覽量

    86169
  • 緩存
    +關(guān)注

    關(guān)注

    1

    文章

    241

    瀏覽量

    26757
  • 數(shù)據(jù)庫(kù)
    +關(guān)注

    關(guān)注

    7

    文章

    3846

    瀏覽量

    64685
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    829

    瀏覽量

    26742
  • Redis
    +關(guān)注

    關(guān)注

    0

    文章

    378

    瀏覽量

    10939
收藏 人收藏

    評(píng)論

    相關(guān)推薦

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

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

    Redis的內(nèi)存淘汰機(jī)制

    redis淘汰策略
    發(fā)表于 09-27 07:55

    淺析Redis的過(guò)期機(jī)制

    Redis數(shù)據(jù)過(guò)期策略詳解
    發(fā)表于 10-12 15:12

    簡(jiǎn)單介紹MySQL延遲主從復(fù)制

    MySQL 5.6 已經(jīng)支持延遲復(fù)制, 可設(shè)置備節(jié)點(diǎn)的延遲時(shí)間, 延遲復(fù)制是有意義的,例如防止主節(jié)點(diǎn)數(shù)據(jù)誤刪,查看數(shù)據(jù)庫(kù)歷史狀態(tài)等。
    的頭像 發(fā)表于 02-09 09:05 ?4084次閱讀

    redis緩存mysql數(shù)據(jù)

    RedisMysql數(shù)據(jù)庫(kù)緩存,必須解決2個(gè)問(wèn)題。首先,應(yīng)該確定用何種數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)來(lái)自Mysql的數(shù)據(jù);在確定數(shù)據(jù)結(jié)構(gòu)之后,還要考慮用什么標(biāo)識(shí)作為該數(shù)據(jù)結(jié)構(gòu)的鍵。
    的頭像 發(fā)表于 02-09 15:42 ?4094次閱讀

    RedisMySQL保持?jǐn)?shù)據(jù)統(tǒng)一的方法介紹

    在高并發(fā)的業(yè)務(wù)場(chǎng)景下,數(shù)據(jù)庫(kù)大多數(shù)情況都是用戶并發(fā)訪問(wèn)最薄弱的環(huán)節(jié)。所以,就需要使用redis做一個(gè)緩沖操作,讓請(qǐng)求先訪問(wèn)到redis,而不是直接訪問(wèn)MySQL等數(shù)據(jù)庫(kù)。
    的頭像 發(fā)表于 09-28 02:42 ?2291次閱讀
    <b class='flag-5'>Redis</b>和<b class='flag-5'>MySQL</b>保持?jǐn)?shù)據(jù)統(tǒng)一的方法介紹

    mysql_redisMySQL中操作Redis?

    ./oschina_soft/gitee-mysql_redis.zip
    發(fā)表于 06-22 14:35 ?2次下載
    <b class='flag-5'>mysql_redis</b>在<b class='flag-5'>MySQL</b>中操作<b class='flag-5'>Redis</b>?

    先寫(xiě) Redis再寫(xiě) MySQL的區(qū)別

    請(qǐng)求 A、B 都是先寫(xiě) MySQL,然后再寫(xiě) Redis,在高并發(fā)情況下,如果請(qǐng)求 A 在寫(xiě) Redis 時(shí)卡了一會(huì),請(qǐng)求 B 已經(jīng)依次完成數(shù)據(jù)的更新,就會(huì)出現(xiàn)圖中的問(wèn)題。
    發(fā)表于 03-01 12:25 ?737次閱讀

    Redis10大性能優(yōu)化策略

    例如,我的機(jī)器配置比較低,當(dāng)延遲為 2ms 時(shí),我就認(rèn)為 Redis 變慢了,但是如果你的硬件配置比較高,那么在你的運(yùn)行環(huán)境下,可能延遲是 0.5ms 時(shí)就可以認(rèn)為 Redis 變慢了
    的頭像 發(fā)表于 07-04 10:21 ?905次閱讀
    <b class='flag-5'>Redis</b>10大性能優(yōu)化<b class='flag-5'>策略</b>

    Redis 的數(shù)據(jù)清理策略

    本文整理 Redis 的數(shù)據(jù)清理策略所有代碼來(lái)自 Redis version :5.0, 不同版本的 Redis 策略可能有調(diào)整
    發(fā)表于 09-19 14:24 ?412次閱讀
    <b class='flag-5'>Redis</b> 的數(shù)據(jù)清理<b class='flag-5'>策略</b>

    Redis的刪除策略和內(nèi)存淘汰機(jī)制介紹

    Redis過(guò)期鍵的刪除策略Redis的過(guò)期刪除策略就是:惰性刪除和定期刪除兩種策略配合使用。 惰性刪除:
    的頭像 發(fā)表于 10-09 11:06 ?521次閱讀

    SpringBoot AOP + Redis 延時(shí)功能實(shí)戰(zhàn)

    注意:要知道經(jīng)常修改的數(shù)據(jù)表不適合使用Redis,因?yàn)?b class='flag-5'>雙策略執(zhí)行的結(jié)果是把Redis中保存的那條數(shù)據(jù)刪除了,以后的查詢(xún)就都會(huì)去查詢(xún)數(shù)據(jù)庫(kù)。
    的頭像 發(fā)表于 10-13 16:08 ?673次閱讀
    SpringBoot AOP + <b class='flag-5'>Redis</b> 延時(shí)<b class='flag-5'>雙</b><b class='flag-5'>刪</b>功能實(shí)戰(zhàn)

    redismysql的區(qū)別

    RedisMySQL是兩種常見(jiàn)的數(shù)據(jù)庫(kù)管理系統(tǒng),兩者在很多方面存在差異,本文將詳細(xì)分析RedisMySQL的區(qū)別。 數(shù)據(jù)模型: Redis
    的頭像 發(fā)表于 11-16 11:21 ?1103次閱讀

    redismysql如何保持?jǐn)?shù)據(jù)一致性

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

    redis的淘汰策略

    Redis是一種基于內(nèi)存的鍵值存儲(chǔ)系統(tǒng),為了充分利用內(nèi)存,Redis采用了一些淘汰策略來(lái)管理內(nèi)存空間。淘汰策略的作用是當(dāng)內(nèi)存空間不足時(shí),選擇合適的數(shù)據(jù)對(duì)象進(jìn)行淘汰,釋放出更多的內(nèi)存空間
    的頭像 發(fā)表于 12-04 16:23 ?594次閱讀
    百家乐官网赌场讨论群| 百家乐官网游戏出售| 扑克百家乐麻将筹码防伪| 三合四局24向黄泉| 现场百家乐官网百家乐官网| 顶级赌场手机版官方| 网络百家乐赌博视频| 百家乐官网路单怎样| 百家乐官网看单技术| 大发888怎么玩能赢| 稳赢百家乐的玩法技巧| 鼎龙百家乐官网的玩法技巧和规则| 百家乐官网有秘技吗| 一起pk棋牌游戏下载| 百家乐五湖四海娱乐| 百家乐官网天下| 网上百家乐官网大赢家筹码| 天天乐娱乐| 永利高a1| 百家乐官网| 百家乐官网心术| 百家乐官网视频看不到| 百家乐7scs娱乐网| 百家乐优惠现金| 博彩百家乐官网字谜总汇| 澳门百家乐官网搏牌规则| 百家乐怎样赢| 大发88817| 大发888 真钱娱乐场| 网络百家乐大转轮| 澳门百家乐园游戏| 什么叫百家乐官网的玩法技巧和规则| 网上百家乐官网赢钱公式| 金昌市| 日博网| 大发888古怪猴子| 威尼斯人娱乐城可信吗| 百家乐最佳注码法| 百家乐最好的玩法| 百家乐官网平游戏| 百家乐官网赌场娱乐网规则|