一、背景
在高并發(fā)場(chǎng)景中,為防止大量請(qǐng)求直接訪問(wèn)數(shù)據(jù)庫(kù),緩解數(shù)據(jù)庫(kù)壓力,常用的方式一般會(huì)增加緩存層起到緩沖作用,減少數(shù)據(jù)庫(kù)壓力。引入緩存,就會(huì)涉及到緩存與數(shù)據(jù)庫(kù)中數(shù)據(jù)如何保持一致性問(wèn)題,本文將對(duì)幾種緩存與數(shù)據(jù)庫(kù)保證數(shù)據(jù)一致性的使用方式進(jìn)行分析。為保證高并發(fā)性能,以下分析場(chǎng)景不考慮執(zhí)行的原子性及加鎖等強(qiáng)一致性要求的場(chǎng)景,僅追求最終一致性。
二、讀取過(guò)程
?讀緩存
?如果緩存里沒(méi)有值,那就讀取數(shù)據(jù)庫(kù)的值
?同時(shí)把這個(gè)值寫進(jìn)緩存中
三、更新過(guò)程
更新操作有多種策略,各有優(yōu)劣,主要針對(duì)此場(chǎng)景進(jìn)行分析
策略 1:先更新 db,再刪除緩存(常用的 Cache-Aside Pattern旁路緩存)
問(wèn)題:
1. 如果更新 db 成功,刪緩存失敗,將導(dǎo)致數(shù)據(jù)不一致
2. 極端場(chǎng)景,請(qǐng)求 A 讀,B 寫
1) 此時(shí)緩存剛好失效 2)A 查庫(kù)得到舊值 3)B 更新 DB 成功
4)B 刪除緩存 5)A 將查到的舊值更新到緩存中
此場(chǎng)景的發(fā)生需要步驟 2)查 db 始終慢于 3)的更新 db,才能導(dǎo)致 4)先于 5)執(zhí)行,通常 db 的查詢是要快于寫入的,所以此極端場(chǎng)景的產(chǎn)生過(guò)于嚴(yán)格,不易發(fā)生
策略 2:先更新 db, 再更新緩存
問(wèn)題:
1. 并發(fā)更新場(chǎng)景下,更新緩存會(huì)導(dǎo)致數(shù)據(jù)不一致
2. 根據(jù)讀寫比,考慮是否有必要頻繁同步更新緩存,而且,如果構(gòu)造緩存中數(shù)據(jù)過(guò)于復(fù)雜,或者數(shù)據(jù)更新頻繁,但是讀取并不頻繁的情況,還會(huì)造成不必要的性能損耗
此種方式不推薦
策略 3: 先更新緩存,再更新 db
同上,不推薦
策略 4:先刪緩存,再更新 db
??先刪緩存,雖然解決了策略 1 中,后刪緩存如果失敗的場(chǎng)景,但也會(huì)發(fā)生不一致的問(wèn)題
例如:請(qǐng)求 A 刪除緩存,這時(shí)請(qǐng)求 B 來(lái)查,就會(huì)擊穿到數(shù)據(jù)庫(kù),B 讀取到舊的值后寫入緩存,A 正常更新 db, 由于時(shí)間差導(dǎo)致數(shù)據(jù)不一致的情況
策略 5:緩存延時(shí)雙刪
??該策略兼容了策略 1 和策略 4, 解決了先刪緩存還是后刪緩存的問(wèn)題,如策略 1 中,更新 db 后刪緩存失敗和策略 4 中的不一致場(chǎng)景,該策略可以將延時(shí)時(shí)間內(nèi)(比如延時(shí) 10ms)所造成的緩存臟數(shù)據(jù),再次刪除。但是,如果延時(shí)刪緩存失敗,策略 4 中不一致問(wèn)題還會(huì)發(fā)生,同時(shí)延時(shí)的實(shí)現(xiàn),如創(chuàng)建線程,或者引入 mq 異步,可能會(huì)增加系統(tǒng)復(fù)雜度問(wèn)題。
策略 6:變種雙刪,前置緩存過(guò)期時(shí)間
?該策略針對(duì)策略 1 中后刪緩存失敗的場(chǎng)景,前置一層緩存數(shù)據(jù)過(guò)期時(shí)間(具體時(shí)間根據(jù)自身系統(tǒng)本身評(píng)估,如可覆蓋 db 讀寫耗時(shí)或一致性容忍度等),更新 db 后就算刪緩存失敗,在 expire 時(shí)間后也能保證緩存中無(wú)數(shù)據(jù)。同時(shí),前置 expire 失敗,或者更新 db 失敗,都不會(huì)影響數(shù)據(jù)一致。
能夠解決策略 4 中的問(wèn)題:請(qǐng)求 A 刪除緩存,這時(shí)請(qǐng)求 B 來(lái)查,就會(huì)擊穿到數(shù)據(jù)庫(kù),B 讀取到舊的值后寫入緩存,A 正常更新 db, 由于時(shí)間差導(dǎo)致數(shù)據(jù)不一致的情況,描述圖如下:
??本策略中步驟 1 為 expire 緩存,不會(huì)發(fā)生擊穿緩存到數(shù)據(jù)庫(kù)的情況,數(shù)據(jù)將直接返回。除非更極端情況,如下圖:
expire 時(shí)間沒(méi)有覆蓋住更新 db 的耗時(shí),類似策略 1 中極端場(chǎng)景,此處不贅述
四、總結(jié)
對(duì)于每種方案策略,各有利弊,但一致性問(wèn)題始終存在(文章開(kāi)頭排除了原子性和鎖),只是發(fā)生的幾率在一點(diǎn)點(diǎn)慢慢變小了,方案的評(píng)估不僅要根據(jù)自身系統(tǒng)的業(yè)務(wù)場(chǎng)景,如讀寫比、并發(fā)量、一致性容忍度,還要考慮系統(tǒng)復(fù)雜度,投入產(chǎn)出比等,尋找最合適的方案。
審核編輯:劉清
-
數(shù)據(jù)庫(kù)
+關(guān)注
關(guān)注
7文章
3739瀏覽量
64176
原文標(biāo)題:緩存與數(shù)據(jù)庫(kù)雙寫一致性幾種策略分析
文章出處:【微信號(hào):OSC開(kāi)源社區(qū),微信公眾號(hào):OSC開(kāi)源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論