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

云原生和數(shù)據(jù)庫哪個好一些?
Oracle報錯“system01.dbf需要更多的恢復來保持一致性”的數(shù)據(jù)恢復案例

一致性測試系統(tǒng)的技術(shù)原理和也應用場景
異構(gòu)計算下緩存一致性的重要性

Oracle數(shù)據(jù)恢復—異常斷電后Oracle數(shù)據(jù)庫啟庫報錯的數(shù)據(jù)恢復案例

數(shù)據(jù)庫數(shù)據(jù)恢復—Oracle數(shù)據(jù)庫文件system01.dbf損壞的數(shù)據(jù)恢復案例

LMK05318的ITU-T G.8262一致性測試結(jié)果

分布式云化數(shù)據(jù)庫的優(yōu)缺點分析
級聯(lián)一致性和移相器校準應用手冊

評論