redis 緩存一致性問題

在高并發(fā)的情況下堤器,如果當(dāng)刪除完緩存的時(shí)候昆庇,這時(shí)去更新數(shù)據(jù)庫,但還沒有更新完闸溃,另外一個(gè)請(qǐng)求來查詢數(shù)據(jù)整吆,發(fā)現(xiàn)緩存里沒有拱撵,就去數(shù)據(jù)庫里查,以商品庫存為例掂为,如果數(shù)據(jù)庫中產(chǎn)品的庫存是100裕膀,那么查詢到的庫存是100,然后插入緩存勇哗,插入完緩存后,原來那個(gè)更新數(shù)據(jù)庫的線程把數(shù)據(jù)庫更新為了99寸齐,導(dǎo)致數(shù)據(jù)庫與緩存不一致的情況欲诺。

這種情況如何解決比較好呢?

本文從以下三個(gè)部分進(jìn)行淺談:

1渺鹦、講解緩存更新策略

2扰法、對(duì)每種策略進(jìn)行缺點(diǎn)分析

3、針對(duì)缺點(diǎn)給出改進(jìn)方案

對(duì)于緩存和數(shù)據(jù)庫的操作毅厚,主要有以下兩種方式:

1.先刪緩存塞颁,再更新數(shù)據(jù)庫

先刪除緩存,數(shù)據(jù)庫還沒有更新成功吸耿,此時(shí)如果讀取緩存祠锣,緩存不存在,去數(shù)據(jù)庫中讀取到的是舊值咽安,緩存不一致發(fā)生伴网。

img

該方案看似沒毛病。使用先操作緩存(delete)妆棒,再操作數(shù)據(jù)庫澡腾。假如刪除緩存成功,更新數(shù)據(jù)庫失敗了糕珊。緩存里沒有數(shù)據(jù)动分,數(shù)據(jù)庫里是之前的數(shù)據(jù),數(shù)據(jù)沒有不一致红选,對(duì)業(yè)務(wù)無影響澜公。只是下一次讀取,會(huì)多一次cache miss纠脾。

但是如果放在并發(fā)場(chǎng)景下玛瘸,一個(gè)寫請(qǐng)求過來,刪除了緩存苟蹈,準(zhǔn)備更新數(shù)據(jù)庫(還沒更新完成)糊渊。然后一個(gè)讀請(qǐng)求過來,緩存未命中慧脱,從數(shù)據(jù)庫讀取舊數(shù)據(jù)渺绒,再次放到緩存中,這時(shí)候,數(shù)據(jù)庫更新完成了宗兼。此時(shí)的情況是躏鱼,緩存中是舊數(shù)據(jù),數(shù)據(jù)庫里面是新數(shù)據(jù)殷绍,數(shù)據(jù)不一致的問題便會(huì)凸顯出來染苛。

img

對(duì)于該場(chǎng)景下的問題,可以采用延時(shí)雙刪策略進(jìn)行解決主到。

延時(shí)雙刪的方案的思路是茶行,為了避免更新數(shù)據(jù)庫的時(shí)候,其他線程從緩存中讀取不到數(shù)據(jù)登钥,就在更新完數(shù)據(jù)庫之后畔师,再sleep一段時(shí)間,然后再次刪除緩存牧牢。sleep的時(shí)間要對(duì)業(yè)務(wù)讀寫緩存的時(shí)間做出評(píng)估看锉,sleep時(shí)間大于讀寫緩存的時(shí)間即可。

流程如下:
  • 線程1刪除緩存塔鳍,然后去更新數(shù)據(jù)庫

  • 線程2來讀緩存伯铣,發(fā)現(xiàn)緩存已經(jīng)被刪除,所以直接從數(shù)據(jù)庫中讀取献幔,這時(shí)候由于線程1還沒有更新完成懂傀,所以讀到的是舊值,然后把舊值寫入緩存

  • 線程1蜡感,根據(jù)估算的時(shí)間蹬蚁,sleep,由于sleep的時(shí)間大于線程2讀數(shù)據(jù)+寫緩存的時(shí)間郑兴,所以緩存被再次刪除

  • 如果還有其他線程來讀取緩存的話犀斋,就會(huì)再次從數(shù)據(jù)庫中讀取到最新值。

img

2.先更新數(shù)據(jù)庫情连,再刪除緩存

既然上述先刪緩存不行叽粹,那如果反過來操作,先更新數(shù)據(jù)庫却舀,再刪除緩存呢虫几?

這個(gè)就更明顯的問題了,更新數(shù)據(jù)庫成功挽拔,如果刪除緩存失敗或者還沒有來得及刪除辆脸,那么,其他線程從緩存中讀取到的就是舊值螃诅,還是會(huì)發(fā)生不一致啡氢。

img

那么這種情況下該怎么處理呢状囱?

基于binlog日志和消息隊(duì)列:
  1. 應(yīng)用直接寫數(shù)據(jù)到數(shù)據(jù)庫中。

  2. 數(shù)據(jù)庫更新binlog日志倘是。

  3. 利用Canal中間件讀取binlog日志亭枷。

  4. Canal借助于限流組件按頻率將數(shù)據(jù)發(fā)到MQ中。

  5. 應(yīng)用監(jiān)控MQ通道搀崭,將MQ的數(shù)據(jù)更新到Redis緩存中叨粘。

可以看到這種方案對(duì)開發(fā)來說比較輕量,不用太關(guān)心緩存層面瘤睹,而且這個(gè)方案雖然比較重宣鄙,但是卻容易形成統(tǒng)一的解決方案。

img

3.總結(jié)

首先默蚌,我們要明確一點(diǎn),緩存不是更新苇羡,而應(yīng)該是刪除绸吸。

刪除緩存有兩種方式:
  • 先刪除緩存,再更新數(shù)據(jù)庫设江。解決方案是使用延遲雙刪锦茁。
  • 先更新數(shù)據(jù)庫,再刪除緩存叉存。解決方案是消息隊(duì)列或者其他binlog同步码俩,引入消息隊(duì)列會(huì)帶來更多的問題,并不推薦直接使用歼捏。

為什么是刪除而不是更新呢稿存?

我們以先更新數(shù)據(jù)庫,再刪除緩存來舉例瞳秽。

如果是更新的話瓣履,那就是先更新數(shù)據(jù)庫,再更新緩存练俐。

舉個(gè)例子:如果數(shù)據(jù)庫1小時(shí)內(nèi)更新了1000次袖迎,那么緩存也要更新1000次,但是這個(gè)緩存可能在1小時(shí)內(nèi)只被讀取了1次腺晾,那么這1000次的更新有必要嗎燕锥?

反過來,如果是刪除的話悯蝉,就算數(shù)據(jù)庫更新了1000次归形,那么也只是做了1次緩存刪除,只有當(dāng)緩存真正被讀取的時(shí)候才去數(shù)據(jù)庫加載泉粉。

針對(duì)緩存一致性要求不是很高的場(chǎng)景连霉,那么只通過設(shè)置超時(shí)時(shí)間就可以了榴芳。其實(shí),如果不是很高的并發(fā)跺撼,無論你選擇先刪緩存還是后刪緩存的方式窟感,都幾乎很少能產(chǎn)生這種問題,但是在高并發(fā)下歉井,你應(yīng)該知道怎么解決問題柿祈。

最后,個(gè)人認(rèn)為哈哩至,沒有十全十美的解決方案躏嚎,總是需要犧牲一點(diǎn)東西滴。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末菩貌,一起剝皮案震驚了整個(gè)濱河市卢佣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌箭阶,老刑警劉巖虚茶,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異仇参,居然都是意外死亡嘹叫,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門诈乒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來罩扇,“玉大人,你說我怎么就攤上這事怕磨∥辜ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵癌压,是天一觀的道長(zhǎng)仰泻。 經(jīng)常有香客問我,道長(zhǎng)滩届,這世上最難降的妖魔是什么集侯? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮帜消,結(jié)果婚禮上棠枉,老公的妹妹穿的比我還像新娘。我一直安慰自己泡挺,他們只是感情好辈讶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著娄猫,像睡著了一般贱除。 火紅的嫁衣襯著肌膚如雪生闲。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天月幌,我揣著相機(jī)與錄音碍讯,去河邊找鬼。 笑死扯躺,一個(gè)胖子當(dāng)著我的面吹牛捉兴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播录语,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼倍啥,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了澎埠?” 一聲冷哼從身側(cè)響起虽缕,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蒲稳,沒想到半個(gè)月后彼宠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡弟塞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拙已。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片决记。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖倍踪,靈堂內(nèi)的尸體忽然破棺而出系宫,到底是詐尸還是另有隱情,我是刑警寧澤建车,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布扩借,位于F島的核電站,受9級(jí)特大地震影響缤至,放射性物質(zhì)發(fā)生泄漏潮罪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一领斥、第九天 我趴在偏房一處隱蔽的房頂上張望嫉到。 院中可真熱鬧,春花似錦月洛、人聲如沸何恶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽细层。三九已至惜辑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間疫赎,已是汗流浹背盛撑。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留虚缎,地道東北人撵彻。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像实牡,于是被迫代替她去往敵國(guó)和親陌僵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容