偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

到底是先更新數(shù)據(jù)庫(kù)還是先更新緩存?

存儲(chǔ) 存儲(chǔ)軟件
很多小伙伴最近都在問(wèn)我,在系統(tǒng)中引入緩存后,當(dāng)向數(shù)據(jù)庫(kù)中寫(xiě)入數(shù)據(jù)時(shí),是先寫(xiě)數(shù)據(jù)庫(kù)還是先寫(xiě)緩存呢?先寫(xiě)數(shù)據(jù)庫(kù)和先寫(xiě)緩存有什么區(qū)別嗎?今天,我們就一起來(lái)聊聊這個(gè)話(huà)題。

[[388559]]

很多小伙伴最近都在問(wèn)我,在系統(tǒng)中引入緩存后,當(dāng)向數(shù)據(jù)庫(kù)中寫(xiě)入數(shù)據(jù)時(shí),是先寫(xiě)數(shù)據(jù)庫(kù)還是先寫(xiě)緩存呢?先寫(xiě)數(shù)據(jù)庫(kù)和先寫(xiě)緩存有什么區(qū)別嗎?今天,我們就一起來(lái)聊聊這個(gè)話(huà)題。

從本質(zhì)上講,無(wú)論是先寫(xiě)數(shù)據(jù)庫(kù)還是先寫(xiě)緩存,都是為了保證數(shù)據(jù)庫(kù)和緩存的數(shù)據(jù)一致,也就是我們常說(shuō)的數(shù)據(jù)一致性。

隨著互聯(lián)網(wǎng)的高速發(fā)展,當(dāng)今時(shí)代已然從IT時(shí)代進(jìn)入到DT時(shí)代?;ヂ?lián)網(wǎng)系統(tǒng)架構(gòu)也已經(jīng)由最初的單體架構(gòu)轉(zhuǎn)變?yōu)榉植际?、微服?wù)架構(gòu)模式。從數(shù)據(jù)體量上來(lái)看,各系統(tǒng)存儲(chǔ)的數(shù)據(jù)量越來(lái)越大,數(shù)據(jù)的查詢(xún)性能越來(lái)越低。此時(shí),就需要我們不斷的進(jìn)行優(yōu)化,一種常用的優(yōu)化手段就是引入緩存。而引入緩存后,我們?cè)谙驍?shù)據(jù)庫(kù)插入數(shù)據(jù)時(shí),到底是先更新數(shù)據(jù)庫(kù)還是先更新緩存呢?

緩存的一般使用

緩存,從本質(zhì)上講,是為了更好的協(xié)調(diào)兩個(gè)速度差異比較大的組件而引入的一種中間緩存層。例如,如果需要將數(shù)據(jù)讀入CPU進(jìn)行計(jì)算處理,由于CPU的運(yùn)算速度是非常快的,而磁盤(pán)的IO處理相比于CPU來(lái)說(shuō),慢了很多數(shù)量級(jí),每次從磁盤(pán)讀取數(shù)據(jù),勢(shì)必會(huì)造成CPU長(zhǎng)時(shí)間并且頻繁等待磁盤(pán)IO。此時(shí),我們就可以通過(guò)內(nèi)存來(lái)緩和CPU和磁盤(pán)之間的速度差異。

從緩存的使用上來(lái)說(shuō),一般是按照如下的流程來(lái)使用緩存。

我們也可以表示成如下的序列圖。

在上面的使用示例中,我們只是簡(jiǎn)單的將數(shù)據(jù)放入了緩存,最多為緩存設(shè)置一個(gè)過(guò)期時(shí)間,到期后,緩存自然就會(huì)被清除,后續(xù)的請(qǐng)求由于在緩存中獲取不到數(shù)據(jù),又會(huì)從數(shù)據(jù)庫(kù)中獲取數(shù)據(jù),將數(shù)據(jù)寫(xiě)入緩存。

但是在后續(xù)更新數(shù)據(jù)的操作中,是更新完數(shù)據(jù)庫(kù),接下來(lái)更新緩存還是刪除緩存?又或者是先刪除緩存,再更新數(shù)據(jù)庫(kù)?

緩存更新策略

從理論上來(lái)說(shuō),給緩存設(shè)置過(guò)期時(shí)間,其實(shí)是一種最終一致性的表現(xiàn)。這種方案下,可以對(duì)存入緩存的數(shù)據(jù)設(shè)置過(guò)期時(shí)間,所有的寫(xiě)操作以數(shù)據(jù)庫(kù)為準(zhǔn),對(duì)緩存操作只是盡最大努力即可。也就是說(shuō)如果數(shù)據(jù)庫(kù)寫(xiě)成功,緩存更新失敗,那么只要到達(dá)過(guò)期時(shí)間,則后面的讀請(qǐng)求自然會(huì)從數(shù)據(jù)庫(kù)中讀取新值然后回填緩存。這也是一般情況下,使用的最多的一種方式。

先更新數(shù)據(jù)庫(kù)再更新緩存

其實(shí),這種方案很多有經(jīng)驗(yàn)的小伙伴是很反對(duì)的,為啥,我們來(lái)分析下。

首先,這種方案會(huì)有線(xiàn)程安全的問(wèn)題。

例如,同時(shí)有線(xiàn)程A和線(xiàn)程B對(duì)數(shù)據(jù)進(jìn)行更新操作,可能會(huì)出現(xiàn)下面的執(zhí)行順序。

(1) 線(xiàn)程A更新了數(shù)據(jù)庫(kù)

(2) 線(xiàn)程B更新了數(shù)據(jù)庫(kù)

(3) 線(xiàn)程B更新了緩存

(4) 線(xiàn)程A更新了緩存

此時(shí)就會(huì)出現(xiàn)數(shù)據(jù)庫(kù)中的數(shù)據(jù)與緩存的數(shù)據(jù)不一致的情況,這是因?yàn)榫€(xiàn)程A先更新了數(shù)據(jù)庫(kù),可能因?yàn)榫W(wǎng)絡(luò)等異常情況,線(xiàn)程B更新完數(shù)據(jù)庫(kù)進(jìn)而更新了緩存,當(dāng)線(xiàn)程B更新完緩存后,線(xiàn)程A才更新緩存,這就導(dǎo)致了數(shù)據(jù)庫(kù)數(shù)據(jù)與緩存數(shù)據(jù)的不一致。

其次,這種方案也有其不適用的業(yè)務(wù)場(chǎng)景。

首先一個(gè)業(yè)務(wù)場(chǎng)景就是數(shù)據(jù)庫(kù)寫(xiě)多讀少的場(chǎng)景,這種場(chǎng)景下采用先更新數(shù)據(jù)庫(kù)再更新緩存的策略,就會(huì)導(dǎo)致緩存并未被讀取就會(huì)被頻繁的更新,極大的浪費(fèi)了服務(wù)器的性能。

再一個(gè)業(yè)務(wù)場(chǎng)景就是數(shù)據(jù)庫(kù)中的數(shù)據(jù)不是直接寫(xiě)入緩存的,而是需要大量的復(fù)雜運(yùn)算,將運(yùn)算結(jié)果寫(xiě)入緩存。如果這種場(chǎng)景下使用先更新數(shù)據(jù)庫(kù)再更新緩存的策略,也會(huì)造成服務(wù)器資源的浪費(fèi)。

先刪除緩存再更新數(shù)據(jù)庫(kù)

先刪除緩存再更新數(shù)據(jù)庫(kù)的方案也存在著線(xiàn)程安全的問(wèn)題,例如,線(xiàn)程A更新緩存,同時(shí),線(xiàn)程B讀取緩存的數(shù)據(jù)。可能會(huì)出現(xiàn)下面的執(zhí)行順序。

(1) 線(xiàn)程A刪除緩存

(2) 線(xiàn)程B查詢(xún)緩存,發(fā)現(xiàn)緩存中沒(méi)有想要的數(shù)據(jù)

(3) 線(xiàn)程B查詢(xún)數(shù)據(jù)庫(kù)中的舊數(shù)據(jù)

(4) 線(xiàn)程B將查詢(xún)到的舊數(shù)據(jù)寫(xiě)入緩存

(5) 線(xiàn)程A將新數(shù)據(jù)寫(xiě)入數(shù)據(jù)庫(kù)

此時(shí),就出現(xiàn)了數(shù)據(jù)庫(kù)中的數(shù)據(jù)和緩存中的數(shù)據(jù)不一致的情況。如果刪除緩存失敗,也會(huì)出現(xiàn)數(shù)據(jù)庫(kù)數(shù)據(jù)和緩存數(shù)據(jù)不一致的現(xiàn)象。

先更新數(shù)據(jù)庫(kù)再刪除緩存

首先,這種方式也有極小的概率發(fā)生數(shù)據(jù)庫(kù)數(shù)據(jù)和緩存數(shù)據(jù)不一致的情況,例如,線(xiàn)程A做查詢(xún)操作,線(xiàn)程B執(zhí)行更新操作,其執(zhí)行的順序如下所示。

(1)緩存剛好失效

(2)請(qǐng)求A查詢(xún)數(shù)據(jù)庫(kù),獲取到數(shù)據(jù)庫(kù)中的舊值

(3)請(qǐng)求B將新值寫(xiě)入數(shù)據(jù)庫(kù)

(4)請(qǐng)求B刪除緩存

(5)請(qǐng)求A將查到的舊值寫(xiě)入緩存

如果上述順序一旦發(fā)生,就會(huì)造成數(shù)據(jù)庫(kù)中的數(shù)據(jù)和緩存中的數(shù)據(jù)不一致的情況發(fā)生。

但是,先更新數(shù)據(jù)庫(kù)再刪除緩存的策略發(fā)生數(shù)據(jù)庫(kù)和緩存數(shù)據(jù)不一致的概率很低,原因就是:(3)的寫(xiě)數(shù)據(jù)庫(kù)操作比步驟(2)的讀數(shù)據(jù)庫(kù)操作耗時(shí)更短,才有可能使得步驟(4)先于步驟(5)執(zhí)行。但是,往往數(shù)據(jù)庫(kù)的讀操作的速度遠(yuǎn)快于寫(xiě)操作,因此步驟(3)耗時(shí)比步驟(2)更短,這一場(chǎng)景很難出現(xiàn)。

如果刪除緩存失敗,也會(huì)出現(xiàn)數(shù)據(jù)庫(kù)數(shù)據(jù)和緩存數(shù)據(jù)不一致的現(xiàn)象。

這樣說(shuō)來(lái),貌似三種方案都不安全呀,那我們?cè)撊绾巫瞿?最重要的就是需要引入重試機(jī)制。

推薦使用

在實(shí)際的生產(chǎn)環(huán)境中,推薦 使用先更新數(shù)據(jù)庫(kù)再刪除緩存 的操作。那么,我們?cè)撊绾谓鉀Q這種策略下的問(wèn)題呢?

有兩種方案,一種是在程序邏輯中處理失敗重試的操作;另外,借助于阿里巴巴開(kāi)源的Canal。

手動(dòng)失敗重試

流程如下所示

(1)更新數(shù)據(jù)庫(kù)數(shù)據(jù);

(2)刪除緩存數(shù)據(jù)失敗

(3)將需要?jiǎng)h除的key發(fā)送至消息隊(duì)列

(4)自己消費(fèi)消息,獲得需要?jiǎng)h除的key

(5)繼續(xù)重試刪除操作,直到成功

這種方案有一個(gè)缺點(diǎn),對(duì)業(yè)務(wù)線(xiàn)代碼造成大量的侵入。

同步數(shù)據(jù)庫(kù)數(shù)據(jù)

先來(lái)一張圖,這種圖從整體架構(gòu)上解決了數(shù)據(jù)庫(kù)數(shù)據(jù)和緩存數(shù)據(jù)不一致的情況。

流程如下圖所示:

(1)更新數(shù)據(jù)庫(kù)數(shù)據(jù)

(2)數(shù)據(jù)庫(kù)將數(shù)據(jù)表數(shù)據(jù)的變更信息寫(xiě)入binlog日志當(dāng)中

(3)訂閱程序獲取所需要的數(shù)據(jù)以及key

(4)程序邏輯中處理具體的業(yè)務(wù)邏輯,接收訂閱binlog、發(fā)起刪除緩存的請(qǐng)求。

(5)嘗試刪除緩存操作,發(fā)現(xiàn)刪除失敗

(6)將這些信息發(fā)送至消息隊(duì)列

(7)重新從消息隊(duì)列中獲得該數(shù)據(jù),重試操作。

本文轉(zhuǎn)載自微信公眾號(hào)「冰河技術(shù)」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系冰河技術(shù)公眾號(hào)。 

 

責(zé)任編輯:武曉燕 來(lái)源: 冰河技術(shù)
相關(guān)推薦

2025-06-12 09:16:54

2021-01-13 05:23:27

緩存數(shù)據(jù)庫(kù)高并發(fā)

2024-12-16 08:01:57

2018-07-13 15:56:39

緩存數(shù)據(jù)庫(kù)數(shù)據(jù)

2023-12-27 13:44:00

數(shù)據(jù)庫(kù)系統(tǒng)分布式

2021-01-29 10:51:48

高并發(fā)數(shù)據(jù)庫(kù)緩存

2019-12-24 09:12:10

運(yùn)維架構(gòu)技術(shù)

2024-03-28 13:13:00

Htmx前端開(kāi)發(fā)框架

2015-04-21 09:20:40

SwfitObject—C

2021-10-15 21:16:00

手機(jī)內(nèi)存漏洞

2011-03-07 17:11:21

云遷移云轉(zhuǎn)型

2018-09-26 14:17:00

編程語(yǔ)言JavaPython

2017-08-09 08:43:02

公有云趨勢(shì)聲勢(shì)

2011-09-05 10:30:51

重構(gòu)代碼庫(kù)業(yè)務(wù)模型

2018-10-09 15:26:19

JavaPython語(yǔ)言

2024-08-20 08:19:43

2022-10-11 10:18:12

數(shù)據(jù)硬盤(pán)開(kāi)機(jī)

2021-05-19 10:44:42

數(shù)據(jù)庫(kù)架構(gòu)技術(shù)

2019-07-23 15:34:29

MySQL存儲(chǔ)引擎

2014-11-17 10:03:23

OpenStack
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)