婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁(yè) > 知識(shí)庫(kù) > MySQL與Redis如何保證數(shù)據(jù)一致性詳解

MySQL與Redis如何保證數(shù)據(jù)一致性詳解

熱門(mén)標(biāo)簽:hbuilder地圖標(biāo)注 400電話申請(qǐng)?jiān)趺纯?/a> 隨州營(yíng)銷(xiāo)電話機(jī)器人怎么樣 機(jī)器人電話機(jī)創(chuàng)意繪畫(huà) 杭州400電話如何申請(qǐng)的 高德地圖標(biāo)注商家在哪 天音通信電話機(jī)器人 江西南昌百應(yīng)電話機(jī)器人 400電話從哪里申請(qǐng)濱州

前言

由于緩存的高并發(fā)和高性能已經(jīng)在各種項(xiàng)目中被廣泛使用,在讀取緩存這方面基本都是一致的,大概都是按照下圖的流程進(jìn)行操作:

但是在更新緩存方面,是更新完數(shù)據(jù)庫(kù)再更新緩存還是直接刪除緩存呢?又或者是先刪除緩存再更新數(shù)據(jù)庫(kù)?在這一點(diǎn)上就值得探討了。

一致性方案

在實(shí)際項(xiàng)目開(kāi)發(fā)中需要保證數(shù)據(jù)庫(kù)和緩存中的數(shù)據(jù)一致,否則人家充值了100塊,不斷刷新卻還是顯示0.01元,豈不是尷尬?從理論上來(lái)說(shuō),為緩存設(shè)置過(guò)期時(shí)間是最終保證數(shù)據(jù)一致性的解決方案,采用這種方案的話,所有的寫(xiě)操作都是以數(shù)據(jù)庫(kù)為準(zhǔn),如果數(shù)據(jù)庫(kù)寫(xiě)入成功但是緩存更新失敗,只要緩存到過(guò)期時(shí)間之后后面讀緩存時(shí)自然會(huì)在數(shù)據(jù)庫(kù)中讀取新的值然后更新緩存。接下來(lái)探討的思路主要的方向是在不依賴(lài)為緩存設(shè)置過(guò)期時(shí)間的前提下如何保證數(shù)據(jù)一致性。這里主要探討三種方案:

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

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

這種方案是普遍被反對(duì)的(在我的認(rèn)知范圍中~),為啥呢?為啥這種方案就被反對(duì)呢?原因主要有兩方面,請(qǐng)聽(tīng)我細(xì)細(xì)道來(lái):

首先從數(shù)據(jù)安全方面考慮,如果同時(shí)有請(qǐng)求A和請(qǐng)求B同時(shí)進(jìn)行操作,A先更新了數(shù)據(jù)庫(kù)的一條數(shù)據(jù),隨后B馬上有更新了該條數(shù)據(jù),但是可能因?yàn)榫W(wǎng)絡(luò)延遲等原因,B卻比A先更新了緩存,就會(huì)出現(xiàn)一種什么情況呢?緩存中的數(shù)據(jù)并不最新的B更新過(guò)的數(shù)據(jù),就導(dǎo)致了數(shù)據(jù)不一致的情況。

其次從業(yè)務(wù)場(chǎng)景方面考慮,如果是一個(gè)寫(xiě)數(shù)據(jù)庫(kù)較多而讀數(shù)據(jù)庫(kù)較少的業(yè)務(wù),如果采用這種方案就會(huì)導(dǎo)致數(shù)據(jù)還沒(méi)讀緩存就會(huì)被頻繁更新,白白浪費(fèi)性能。

綜合以上兩方面的考慮,這種方案果斷pass。下面的兩種方案就是爭(zhēng)議較大的兩種方案了,到底是先刪緩存再更新數(shù)據(jù)庫(kù)還是先更新數(shù)據(jù)庫(kù)再刪除緩存?

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

如果同時(shí)有一個(gè)請(qǐng)求A進(jìn)行更新操作,請(qǐng)求B進(jìn)行查詢(xún)操作,就可能會(huì)出現(xiàn)A請(qǐng)求進(jìn)行寫(xiě)操作前會(huì)刪除緩存,B請(qǐng)求剛好此時(shí)進(jìn)來(lái)發(fā)現(xiàn)緩存是空的,B請(qǐng)求就會(huì)查詢(xún)數(shù)據(jù)庫(kù),如果此時(shí)A請(qǐng)求的寫(xiě)操作還未完成,B請(qǐng)求查詢(xún)到的就還是舊的值,還是會(huì)將舊的值寫(xiě)入緩存,A請(qǐng)求將新的值寫(xiě)入數(shù)據(jù)庫(kù),此時(shí)就會(huì)導(dǎo)致數(shù)據(jù)不一致的問(wèn)題,如果不采用給緩存設(shè)置過(guò)期時(shí)間的策略,該數(shù)據(jù)永遠(yuǎn)都是臟數(shù)據(jù)。

解決這種情況可以采用延時(shí)雙刪的策略,就是在更新數(shù)據(jù)庫(kù)之前先刪除緩存,然后對(duì)數(shù)據(jù)庫(kù)進(jìn)行寫(xiě)入操作,數(shù)據(jù)庫(kù)更新完成之后再次進(jìn)行刪除緩存的操作,目的是刪除讀請(qǐng)求可能造成的緩存臟數(shù)據(jù),第二次刪除緩存之前可以休眠幾秒,具體時(shí)間開(kāi)發(fā)者可以評(píng)估一下自己項(xiàng)目讀數(shù)據(jù)業(yè)務(wù)邏輯的耗時(shí),然后在該耗時(shí)基礎(chǔ)上加幾百ms即可,這么做的目的就是確保讀請(qǐng)求結(jié)束寫(xiě)請(qǐng)求可以刪除讀請(qǐng)求造成的臟數(shù)據(jù)。如果MySQL采用的是讀寫(xiě)分離的架構(gòu),可能由于主從延時(shí)的原因造成數(shù)據(jù)不一致,可以在寫(xiě)操作完成之后根據(jù)主從延時(shí)時(shí)間休眠一下然后再進(jìn)行刪除緩存的操作。延時(shí)雙刪的偽代碼如下:

# 偽代碼
def delay_delete():
    redis.delete('name')  # 更新數(shù)據(jù)庫(kù)之前先刪除緩存
    sql = 'update info set name='lili' where id=1;'  # 更新數(shù)據(jù)庫(kù)
    cursor.execute(sql)  
    time.sleep(1)  # 如果mysql是主從架構(gòu)則休眠主從延時(shí)的時(shí)間再多幾百ms
    redis.delete('name')  # 再次刪除緩存

那會(huì)不會(huì)存在第二次刪除緩存失敗的情況呢?如果第二次刪除失敗,還是會(huì)造成緩存和數(shù)據(jù)庫(kù)不一致的問(wèn)題,又如何解決呢?且看下一種方案。

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

老外提出了一個(gè)緩存更新方案Cache−AsidepatternCache-Aside patternCache−Asidepattern,文章中提到**應(yīng)用程序應(yīng)該從cache中獲取數(shù)據(jù),如果獲取成功直接返回,如果沒(méi)有獲取成功,則從數(shù)據(jù)庫(kù)中獲取,成功后放到緩存中,更新數(shù)據(jù)時(shí)應(yīng)該先把數(shù)據(jù)存到數(shù)據(jù)庫(kù)中成功后再讓緩存失效。**原文如下

If an application updates information, it can follow the write-through strategy by making the modification to the data store, and by invalidating the corresponding item in the cache.
When the item is next required, using the cache-aside strategy will cause the updated data to be retrieved from the data store and added back into the cache.

這種方案會(huì)不會(huì)產(chǎn)生數(shù)據(jù)不一致的情況呢?比如下述這種情況:

有兩個(gè)請(qǐng)求A和B,A進(jìn)行查詢(xún)同時(shí)B進(jìn)行更新,假設(shè)發(fā)生下述情況:

①此時(shí)緩存剛好失效

②請(qǐng)求A 就會(huì)去查詢(xún)數(shù)據(jù)庫(kù)得到一個(gè)舊的值

③請(qǐng)求B將新的值寫(xiě)入數(shù)據(jù)庫(kù)

④請(qǐng)求B寫(xiě)入成功后刪除緩存

⑤請(qǐng)求A將查到的機(jī)制寫(xiě)入緩存,產(chǎn)生臟數(shù)據(jù)...

如果發(fā)聲上述情況,確實(shí)會(huì)產(chǎn)生數(shù)據(jù)不一致的情況,但是XDM想一想,發(fā)生這種情況的概率是多少呢?如果先要產(chǎn)生這種結(jié)果,就必須有一個(gè)條件,就是請(qǐng)求B的操作時(shí)間非常短,短到什么程度呢,就是請(qǐng)求B寫(xiě)入數(shù)據(jù)庫(kù)的操作要比請(qǐng)求A從數(shù)據(jù)庫(kù)中讀取數(shù)據(jù)的速度要快(因?yàn)閞edis非常快,因此操作redis的時(shí)間可以暫且忽略),只有這種情況下④才可能比⑤先發(fā)聲,但是數(shù)據(jù)庫(kù)的讀操作要遠(yuǎn)比寫(xiě)操作快的多,不然做讀寫(xiě)分離干嘛呢?所以這種情況發(fā)生的概率是非常非常非常的低,但是如果強(qiáng)迫癥患者出現(xiàn)必須要解決怎么辦呢?就可以采用給緩存設(shè)置過(guò)期時(shí)間或者采用第二種方案的延時(shí)雙刪策略,保證讀請(qǐng)求完成之后在進(jìn)行刪除操作。

最后的問(wèn)題

還有問(wèn)題呀,就是最終解決方案三可能 出現(xiàn)的極低概率的數(shù)據(jù)不一致的方案是采用方案二的延時(shí)雙刪策略,可是在方案二中也說(shuō)了,如果出現(xiàn)緩存刪除失敗的情況咋辦?那不是還會(huì)出現(xiàn)數(shù)據(jù)不一致的問(wèn)題嗎?這個(gè)問(wèn)題到底如何解決呢?這里提供一個(gè)重試機(jī)制,刪除失敗就重試一次唄,這里提供一種重試的方案。

①更新數(shù)據(jù)庫(kù)
②由于各種原因緩存刪除失敗
③將刪除失敗的緩存放入消息隊(duì)列中
④業(yè)務(wù)代碼從消息隊(duì)列中獲取需要?jiǎng)h除的key
⑤繼續(xù)嘗試刪除操作,直到成功

總結(jié)

到此這篇關(guān)于MySQL與Redis如何保證數(shù)據(jù)一致性的文章就介紹到這了,更多相關(guān)MySQL與Redis數(shù)據(jù)一致性?xún)?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Redis緩存常用4種策略原理詳解
  • 聊一聊Redis與MySQL雙寫(xiě)一致性如何保證
  • 詳解redis緩存與數(shù)據(jù)庫(kù)一致性問(wèn)題解決
  • redis實(shí)現(xiàn)分布式的方法總結(jié)
  • 面試常問(wèn):如何保證Redis緩存和數(shù)據(jù)庫(kù)的數(shù)據(jù)一致性

標(biāo)簽:葫蘆島 保定 招商 昆明 鶴崗 常德 沈陽(yáng) 石嘴山

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《MySQL與Redis如何保證數(shù)據(jù)一致性詳解》,本文關(guān)鍵詞  MySQL,與,Redis,如何,保證,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《MySQL與Redis如何保證數(shù)據(jù)一致性詳解》相關(guān)的同類(lèi)信息!
  • 本頁(yè)收集關(guān)于MySQL與Redis如何保證數(shù)據(jù)一致性詳解的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    主站蜘蛛池模板: 玉溪市| 山丹县| 崇明县| 陇川县| 南丰县| 南召县| 黄浦区| 和龙市| 泰宁县| 西和县| 宜川县| 永定县| 博客| 江川县| 泰州市| 日喀则市| 小金县| 突泉县| 苗栗县| 五华县| 边坝县| 芷江| 临潭县| 盐山县| 类乌齐县| 昆山市| 新化县| 清苑县| 邢台市| 化州市| 丰县| 安乡县| 上饶市| 左贡县| 耒阳市| 金华市| 南江县| 遂昌县| 合阳县| 宁城县| 绥芬河市|