欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談Redis跟MySQL的雙寫(xiě)問(wèn)題解決方案

 更新時(shí)間:2022年02月24日 11:21:37   作者:碼農(nóng)BookSea  
項(xiàng)目中有遇到這個(gè)問(wèn)題,跟MySQL中的數(shù)據(jù)不一致,記錄一下,本文主要介紹了Redis跟MySQL的雙寫(xiě)問(wèn)題解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

項(xiàng)目中有遇到這個(gè)問(wèn)題,跟MySQL中的數(shù)據(jù)不一致,研究一番發(fā)現(xiàn)這里面細(xì)節(jié)并不簡(jiǎn)單,特此記錄一下。

寫(xiě)在前面

嚴(yán)格意義上任何非原子操作都不可能保證一致性,除非用阻塞讀寫(xiě)實(shí)現(xiàn)強(qiáng)一致性,所以緩存架構(gòu)我們追求的目標(biāo)是最終一致性。
緩存就是通過(guò)犧牲強(qiáng)一致性來(lái)提高性能的。

這是由CAP理論決定的。緩存系統(tǒng)適用的場(chǎng)景就是非強(qiáng)一致性的場(chǎng)景,它屬于CAP中的AP。

以下3 種緩存讀寫(xiě)策略各有優(yōu)劣,不存在最佳。

三種讀寫(xiě)緩存策略

Cache-Aside Pattern(旁路緩存模式)

Cache-Aside Pattern,即旁路緩存模式,它的提出是為了盡可能地解決緩存與數(shù)據(jù)庫(kù)的數(shù)據(jù)不一致問(wèn)題。

在這里插入圖片描述

:從緩存讀取數(shù)據(jù),讀到直接返回。如果讀取不到的話,從數(shù)據(jù)庫(kù)加載,寫(xiě)入緩存后,再返回響應(yīng)。
寫(xiě):更新的時(shí)候,先更新數(shù)據(jù)庫(kù),然后再刪除緩存

在這里插入圖片描述

Read-Through/Write-Through(讀寫(xiě)穿透)

Read/Write Through Pattern 中服務(wù)端把 cache 視為主要數(shù)據(jù)存儲(chǔ),從中讀取數(shù)據(jù)并將數(shù)據(jù)寫(xiě)入其中。cache 服務(wù)負(fù)責(zé)將此數(shù)據(jù)讀取和寫(xiě)入 DB,從而減輕了應(yīng)用程序的職責(zé)。

因?yàn)槲覀兘?jīng)常使用的分布式緩存 Redis 并沒(méi)有提供 cache 將數(shù)據(jù)寫(xiě)入DB的功能,所以使用并不多。

寫(xiě):先查 cache,cache 中不存在,直接更新 DB。cache 中存在,則先更新 cache,然后 cache 服務(wù)自己更新 DB(同步更新 cache和DB)。

:從 cache 中讀取數(shù)據(jù),讀取到就直接返回 。讀取不到的話,先從 DB 加載,寫(xiě)入到 cache 后返回響應(yīng)。

Write Behind Pattern(異步緩存寫(xiě)入)

Write Behind Pattern 和 Read/Write Through Pattern 很相似,兩者都是由 cache 服務(wù)來(lái)負(fù)責(zé) cache 和 DB 的讀寫(xiě)。

但是,兩個(gè)又有很大的不同:Read/Write Through 是同步更新 cache 和 DB,而 Write Behind Caching 則是只更新緩存,不直接更新 DB,而是改為異步批量的方式來(lái)更新 DB。

很明顯,這種方式對(duì)數(shù)據(jù)一致性帶來(lái)了更大的挑戰(zhàn),比如cache數(shù)據(jù)可能還沒(méi)異步更新DB的話,cache服務(wù)可能就掛掉了,反而會(huì)帶來(lái)更大的災(zāi)難。

這種策略在我們平時(shí)開(kāi)發(fā)過(guò)程中也非常非常少見(jiàn),但是不代表它的應(yīng)用場(chǎng)景少,比如消息隊(duì)列中消息的異步寫(xiě)入磁盤(pán)、MySQL 的 InnoDB Buffer Pool 機(jī)制都用到了這種策略。

Write Behind Pattern 下 DB 的寫(xiě)性能非常高,非常適合一些數(shù)據(jù)經(jīng)常變化又對(duì)數(shù)據(jù)一致性要求沒(méi)那么高的場(chǎng)景,比如瀏覽量、點(diǎn)贊量。

旁路緩存模式解析

Cache Aside Pattern 的一些疑問(wèn)

旁路緩存模式是我們平時(shí)中使用最多的。下面根據(jù)上面介紹的旁路緩存模式,我們可以有以下幾個(gè)疑問(wèn)。

為什么寫(xiě)操作是刪除緩存,而不是更新緩存

:線程A先發(fā)起一個(gè)寫(xiě)操作,第一步先更新數(shù)據(jù)庫(kù)。線程B再發(fā)起一個(gè)寫(xiě)操作,第二步更新了數(shù)據(jù)庫(kù),由于網(wǎng)絡(luò)等原因,線程B先更新了緩存,線程A更新緩存。

這時(shí)候,緩存保存的是A的數(shù)據(jù)(老數(shù)據(jù)),數(shù)據(jù)庫(kù)保存的是B的數(shù)據(jù)(新數(shù)據(jù)),數(shù)據(jù)不一致了,臟數(shù)據(jù)出現(xiàn)啦。如果是刪除緩存取代更新緩存則不會(huì)出現(xiàn)這個(gè)臟數(shù)據(jù)問(wèn)題。

實(shí)際上要寫(xiě)操作的時(shí)候更新緩存也是可以的,不過(guò)我們需要加一個(gè)鎖/分布式鎖來(lái)保證更新cache的時(shí)候不存在線程安全問(wèn)題。

在寫(xiě)數(shù)據(jù)的過(guò)程中,為什么要先更新DB在刪除緩存

:比如說(shuō)請(qǐng)求1 是寫(xiě)操作,要是先刪除緩存A,請(qǐng)求2是讀操作,先讀緩存A,發(fā)現(xiàn)緩存被刪除了(被請(qǐng)求1刪除了),然后去讀數(shù)據(jù)庫(kù),但是此時(shí)請(qǐng)求1還沒(méi)來(lái)得及把數(shù)據(jù)及時(shí)更新,那么請(qǐng)求2讀的就是舊數(shù)據(jù),并且請(qǐng)求2還會(huì)把讀到的舊數(shù)據(jù)放到緩存中,造成了數(shù)據(jù)的不一致。

其實(shí)要先刪緩存,再更新數(shù)據(jù)庫(kù)也是可以,如采用延時(shí)雙刪策略
休眠1秒,再次淘汰緩存 這么做,可以將1秒內(nèi)所造成的緩存臟數(shù)據(jù),再次刪除。不一定是1秒,看你業(yè)務(wù)決定的,不過(guò)不推薦這種做法,因?yàn)樵谶@1秒內(nèi)可能發(fā)生因素很多,它的不確定性太大。

在寫(xiě)數(shù)據(jù)的過(guò)程中,先更新DB,后刪除cache就沒(méi)有問(wèn)題了么?

答: 理論上來(lái)說(shuō)還是可能會(huì)出現(xiàn)數(shù)據(jù)不一致性的問(wèn)題,不過(guò)概率非常小。

假設(shè)這會(huì)有兩個(gè)請(qǐng)求,一個(gè)請(qǐng)求A做查詢操作,一個(gè)請(qǐng)求B做更新操作,那么會(huì)有如下情形產(chǎn)生

(1)緩存剛好失效
(2)請(qǐng)求A查詢數(shù)據(jù)庫(kù),得一個(gè)舊值
(3)請(qǐng)求B將新值寫(xiě)入數(shù)據(jù)庫(kù)
(4)請(qǐng)求B刪除緩存
(5)請(qǐng)求A將查到的舊值寫(xiě)入緩存 ok,如果發(fā)生上述情況,確實(shí)是會(huì)發(fā)生臟數(shù)據(jù)。

然而,發(fā)生這種情況的概率并不高

發(fā)生上述情況有一個(gè)先天性條件,就是步驟(3)的寫(xiě)數(shù)據(jù)庫(kù)操作比步驟(2)的讀數(shù)據(jù)庫(kù)操作耗時(shí)更短,才有可能使得步驟(4)先于步驟(5)。

可是,仔細(xì)想想,數(shù)據(jù)庫(kù)的讀操作的速度遠(yuǎn)快于寫(xiě)操作的(不然做讀寫(xiě)分離干嘛,做讀寫(xiě)分離的意義就是因?yàn)樽x操作比較快,耗資源少),因此步驟(3)耗時(shí)比步驟(2)更短,這一情形很難出現(xiàn)。

還有其他造成不一致的原因么?

答: 如果刪除緩存過(guò)程中失敗了就會(huì)造成不一致問(wèn)題

如何解決?
使用Canal去訂閱數(shù)據(jù)庫(kù)的binlog,獲得需要操作的數(shù)據(jù)。另起一個(gè)程序,獲得這個(gè)訂閱程序傳來(lái)的信息,進(jìn)行刪除緩存操作。

Cache Aside Pattern 的缺陷

缺陷1:首次請(qǐng)求數(shù)據(jù)一定不在 cache 的問(wèn)題

解決辦法:可以將熱點(diǎn)數(shù)據(jù)提前放入cache 中。

缺陷2:寫(xiě)操作比較頻繁的話導(dǎo)致cache中的數(shù)據(jù)會(huì)被頻繁被刪除,這樣會(huì)影響緩存命中率 。

數(shù)據(jù)庫(kù)和緩存數(shù)據(jù)強(qiáng)一致場(chǎng)景 :更新DB的時(shí)候同樣更新cache,不過(guò)我們需要加一個(gè)鎖/分布式鎖來(lái)保證更新cache的時(shí)候不存在線程安全問(wèn)題??梢远虝旱卦试S數(shù)據(jù)庫(kù)和緩存數(shù)據(jù)不一致的場(chǎng)景 :更新DB的時(shí)候同樣更新cache,但是給緩存加一個(gè)比較短的過(guò)期時(shí)間,這樣的話就可以保證即使數(shù)據(jù)不一致的話影響也比較小。

到此這篇關(guān)于淺談Redis跟MySQL的雙寫(xiě)問(wèn)題解決方案的文章就介紹到這了,更多相關(guān)Redis MySQL雙寫(xiě)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 關(guān)于在Redis中使用Pipelining加速查詢的問(wèn)題

    關(guān)于在Redis中使用Pipelining加速查詢的問(wèn)題

    這篇文章主要介紹了在Redis中使用Pipelining加速查詢,Redis是一個(gè)client-server模式的TCP服務(wù),也被稱為Request/Response協(xié)議的實(shí)現(xiàn),本文通過(guò)一個(gè)例子給大家詳細(xì)介紹,感興趣的朋友一起看看吧
    2022-05-05
  • Redis 有序集合的使用場(chǎng)景

    Redis 有序集合的使用場(chǎng)景

    在Redis的學(xué)習(xí)中,有序集合是一種非常實(shí)用的數(shù)據(jù)結(jié)構(gòu),本文就來(lái)介紹一下Redis 有序集合的使用場(chǎng)景,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • redis在php中常用的語(yǔ)法【推薦】

    redis在php中常用的語(yǔ)法【推薦】

    string是redis最基本的類型,而且string類型是二進(jìn)制安全的。這篇文章主要介紹了redis在php中常用的語(yǔ)法,需要的朋友可以參考下
    2018-08-08
  • 淺析Redis中紅鎖RedLock的實(shí)現(xiàn)原理

    淺析Redis中紅鎖RedLock的實(shí)現(xiàn)原理

    RedLock?是一種分布式鎖的實(shí)現(xiàn)算法,由?Redis?的作者?Salvatore?Sanfilippo(也稱為?Antirez)提出,本文主要為大家詳細(xì)介紹了紅鎖RedLock的實(shí)現(xiàn)原理,感興趣的可以了解下
    2024-02-02
  • redis主從復(fù)制原理的深入講解

    redis主從復(fù)制原理的深入講解

    這篇文章主要給大家介紹了關(guān)于redis主從復(fù)制原理的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用redis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Redis Sorted Set類型使用及應(yīng)用場(chǎng)景

    Redis Sorted Set類型使用及應(yīng)用場(chǎng)景

    Sorted Set是Redis常用的一種是數(shù)據(jù)類型,本文主要介紹了Redis Sorted Set類型使用及應(yīng)用場(chǎng)景,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06
  • Redis實(shí)戰(zhàn)記錄之限制操作頻率

    Redis實(shí)戰(zhàn)記錄之限制操作頻率

    這篇文章主要給大家介紹了關(guān)于Redis實(shí)戰(zhàn)記錄之限制操作頻率的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Redis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Redis過(guò)期數(shù)據(jù)是否會(huì)被立馬刪除

    Redis過(guò)期數(shù)據(jù)是否會(huì)被立馬刪除

    這篇文章主要為大家介紹了Redis過(guò)期數(shù)據(jù)會(huì)被立馬刪除么的問(wèn)題解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • RedisTemplate常用方法大全(面試必備)

    RedisTemplate常用方法大全(面試必備)

    RedisTemplate是SpringData Redis提供的一個(gè)類,本文主要介紹了RedisTemplate常用方法大全,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-05-05
  • 淺談Redis的幾個(gè)過(guò)期策略

    淺談Redis的幾個(gè)過(guò)期策略

    在使用redis時(shí),一般會(huì)設(shè)置一個(gè)過(guò)期時(shí)間,當(dāng)然也有不設(shè)置過(guò)期時(shí)間的,也就是永久不過(guò)期。當(dāng)設(shè)置了過(guò)期時(shí)間,redis是如何判斷是否過(guò)期,以及根據(jù)什么策略來(lái)進(jìn)行刪除的。
    2021-05-05

最新評(píng)論