解決Redis的緩存與數(shù)據(jù)庫(kù)雙寫(xiě)不一致問(wèn)題
一、Cache Aside Pattern
在了解這個(gè)問(wèn)題之前,我們有必要知道緩存+數(shù)據(jù)庫(kù)讀寫(xiě)數(shù)據(jù)的模式,也就是Cache Aside Pattern
(1)讀的時(shí)候:先讀緩存,緩存沒(méi)有的話,就讀數(shù)據(jù)庫(kù),然后取出數(shù)據(jù)后放入緩存,同時(shí)返回響應(yīng);
(2)寫(xiě)的時(shí)候:先更新數(shù)據(jù)庫(kù),然后再刪除緩存。
寫(xiě)的時(shí)候模式分析為什么是刪除緩存,而不是更新緩存?:
①假設(shè)我們有10次寫(xiě),若是更新緩存的話需要更新10次緩存,10次數(shù)據(jù)庫(kù),我們優(yōu)化為只需要?jiǎng)h除一次緩存,更新10次數(shù)據(jù)庫(kù),當(dāng)有一個(gè)讀請(qǐng)求過(guò)來(lái)只是沒(méi)有命中,去數(shù)據(jù)庫(kù)讀取一下,這樣對(duì)性能的影響也不是很大;
②這是 一個(gè) lazy 計(jì)算的思想,不要每次都重新做復(fù)雜的計(jì)算,不管它會(huì)不會(huì)用到,而是讓它到需要被使用的時(shí)候再重新計(jì)算。像mybatis,hibernate,都有懶加載思想。
二、緩存與數(shù)據(jù)庫(kù)雙寫(xiě)不一致
1、雙寫(xiě)不一致情況
線程1在寫(xiě)數(shù)據(jù)庫(kù)與更新緩存之間卡頓了一下,然后線程2在線程1卡頓的這個(gè)空隙去寫(xiě)了數(shù)據(jù)庫(kù)并刷新了緩存,然后線程2都已經(jīng)執(zhí)行完了,線程1又把臟數(shù)據(jù)更新到了緩存,造成了數(shù)據(jù)庫(kù)與緩存不一致。
2、讀寫(xiě)并發(fā)不一致
先更新寫(xiě)操作的,由于中間網(wǎng)絡(luò)問(wèn)題或者什么問(wèn)題造成更新數(shù)據(jù)推后,最后造成了臟數(shù)據(jù)的更新,導(dǎo)致數(shù)據(jù)庫(kù)與緩存雙寫(xiě)不一致。
三、解決方案
(1)對(duì)于并發(fā)幾率很小的數(shù)據(jù)(如個(gè)人維度的訂單數(shù)據(jù)、用戶數(shù)據(jù)等),這種幾乎不用考慮這個(gè)問(wèn)題,很少會(huì)發(fā)生緩存不一致,可以給緩存數(shù)據(jù)加上過(guò)期時(shí)間,每隔一段時(shí)間觸發(fā)讀的主動(dòng)更新即可。
(2)就算并發(fā)很高,如果業(yè)務(wù)上能容忍短時(shí)間的緩存數(shù)據(jù)不一致(如商品名稱,商品分類菜單等),緩存加上過(guò)期時(shí)間依然可以解決大部分業(yè)務(wù)對(duì)于緩存的要求。
1、消息隊(duì)列串行化
(1)主要思路:在后臺(tái)進(jìn)程中我們可以創(chuàng)建多個(gè)隊(duì)列,然后根據(jù)hash算法將寫(xiě)請(qǐng)求路由到不同的隊(duì)列中,當(dāng)來(lái)讀請(qǐng)求的時(shí)候,就加入隊(duì)列中,當(dāng)寫(xiě)請(qǐng)求處理完畢后,再去處理讀請(qǐng)求。
(2)分析:如果對(duì)于同一份數(shù)據(jù)有多個(gè)寫(xiě)請(qǐng)求同時(shí)在隊(duì)列中,那么來(lái)一個(gè)讀請(qǐng)求中加入隊(duì)列中之后,一般寫(xiě)請(qǐng)求耗時(shí)比較久,那么讀請(qǐng)求會(huì)需要很久才能返回,這樣會(huì)特別影響性能,但能保證一致性(一般情況下建議不要用)
2、加分布式鎖
通過(guò)加分布式讀寫(xiě)鎖保證并發(fā)讀寫(xiě)或寫(xiě)寫(xiě)的時(shí)候按順序排好隊(duì),讀讀的時(shí)候相當(dāng)于無(wú)鎖。
3、用阿里開(kāi)源的canal
可以用阿里開(kāi)源的canal通過(guò)監(jiān)聽(tīng)數(shù)據(jù)庫(kù)的binlog日志及時(shí)的去修改緩存,但是引入了新的中間件,增加了系統(tǒng)的復(fù)雜度
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Redis3.2.11在centos9安裝與卸載過(guò)程詳解
這篇文章主要介紹了Redis3.2.11在centos9安裝與卸載過(guò)程詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01redis分布式Jedis類型轉(zhuǎn)換的異常深入研究
這篇文章主要介紹了redis分布式Jedis類型轉(zhuǎn)換的異常深入研究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03