自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

高并發(fā)場(chǎng)景下,到底先更新緩存還是先更新數(shù)據(jù)庫(kù)?

存儲(chǔ) 存儲(chǔ)軟件 數(shù)據(jù)庫(kù)運(yùn)維
在大型系統(tǒng)中,為了減少數(shù)據(jù)庫(kù)壓力通常會(huì)引入緩存機(jī)制,一旦引入緩存又很容易造成緩存和數(shù)據(jù)庫(kù)數(shù)據(jù)不一致,導(dǎo)致用戶看到的是舊數(shù)據(jù)。

 [[375473]]

本文轉(zhuǎn)載自微信公眾號(hào)「愛(ài)笑的架構(gòu)師」,作者雷架。轉(zhuǎn)載本文請(qǐng)聯(lián)系愛(ài)笑的架構(gòu)師公眾號(hào)。  

在大型系統(tǒng)中,為了減少數(shù)據(jù)庫(kù)壓力通常會(huì)引入緩存機(jī)制,一旦引入緩存又很容易造成緩存和數(shù)據(jù)庫(kù)數(shù)據(jù)不一致,導(dǎo)致用戶看到的是舊數(shù)據(jù)。

為了減少數(shù)據(jù)不一致的情況,更新緩存和數(shù)據(jù)庫(kù)的機(jī)制顯得尤為重要,接下來(lái)帶領(lǐng)大家踩踩坑。

Cache aside

Cache aside也就是旁路緩存,是比較常用的緩存策略。

(1)讀請(qǐng)求常見(jiàn)流程

Cache aside 讀請(qǐng)求

應(yīng)用首先會(huì)判斷緩存是否有該數(shù)據(jù),緩存命中直接返回?cái)?shù)據(jù),緩存未命中即緩存穿透到數(shù)據(jù)庫(kù),從數(shù)據(jù)庫(kù)查詢數(shù)據(jù)然后回寫(xiě)到緩存中,最后返回?cái)?shù)據(jù)給客戶端。

(2)寫(xiě)請(qǐng)求常見(jiàn)流程

Cache aside 寫(xiě)請(qǐng)求

首先更新數(shù)據(jù)庫(kù),然后從緩存中刪除該數(shù)據(jù)。

看了寫(xiě)請(qǐng)求的圖之后,有些同學(xué)可能要問(wèn)了:為什么要?jiǎng)h除緩存,直接更新不就行了?這里涉及到幾個(gè)坑,我們一步一步踩下去。

Cache aside踩坑

Cache aside策略如果用錯(cuò)就會(huì)遇到深坑,下面我們來(lái)逐個(gè)踩。

踩坑一:先更新數(shù)據(jù)庫(kù),再更新緩存

如果同時(shí)有兩個(gè)寫(xiě)請(qǐng)求需要更新數(shù)據(jù),每個(gè)寫(xiě)請(qǐng)求都先更新數(shù)據(jù)庫(kù)再更新緩存,在并發(fā)場(chǎng)景可能會(huì)出現(xiàn)數(shù)據(jù)不一致的情況。

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

如上圖的執(zhí)行過(guò)程:

(1)寫(xiě)請(qǐng)求1更新數(shù)據(jù)庫(kù),將 age 字段更新為18;

(2)寫(xiě)請(qǐng)求2更新數(shù)據(jù)庫(kù),將 age 字段更新為20;

(3)寫(xiě)請(qǐng)求2更新緩存,緩存 age 設(shè)置為20;

(4)寫(xiě)請(qǐng)求1更新緩存,緩存 age 設(shè)置為18;

執(zhí)行完預(yù)期結(jié)果是數(shù)據(jù)庫(kù) age 為20,緩存 age 為20,結(jié)果緩存 age為18,這就造成了緩存數(shù)據(jù)不是最新的,出現(xiàn)了臟數(shù)據(jù)。

踩坑二:先刪緩存,再更新數(shù)據(jù)庫(kù)

如果寫(xiě)請(qǐng)求的處理流程是先刪緩存再更新數(shù)據(jù)庫(kù),在一個(gè)讀請(qǐng)求和一個(gè)寫(xiě)請(qǐng)求并發(fā)場(chǎng)景下可能會(huì)出現(xiàn)數(shù)據(jù)不一致情況。

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

如上圖的執(zhí)行過(guò)程:

(1)寫(xiě)請(qǐng)求刪除緩存數(shù)據(jù);

(2)讀請(qǐng)求查詢緩存未擊中(Hit Miss),緊接著查詢數(shù)據(jù)庫(kù),將返回的數(shù)據(jù)回寫(xiě)到緩存中;

(3)寫(xiě)請(qǐng)求更新數(shù)據(jù)庫(kù)。

整個(gè)流程下來(lái)發(fā)現(xiàn)數(shù)據(jù)庫(kù)中age為20,緩存中age為18,緩存和數(shù)據(jù)庫(kù)數(shù)據(jù)不一致,緩存出現(xiàn)了臟數(shù)據(jù)。

踩坑三:先更新數(shù)據(jù)庫(kù),再刪除緩存

在實(shí)際的系統(tǒng)中針對(duì)寫(xiě)請(qǐng)求還是推薦先更新數(shù)據(jù)庫(kù)再刪除緩存,但是在理論上還是存在問(wèn)題,以下面這個(gè)例子說(shuō)明。

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

如上圖的執(zhí)行過(guò)程:

(1)讀請(qǐng)求先查詢緩存,緩存未擊中,查詢數(shù)據(jù)庫(kù)返回?cái)?shù)據(jù);

(2)寫(xiě)請(qǐng)求更新數(shù)據(jù)庫(kù),刪除緩存;

(3)讀請(qǐng)求回寫(xiě)緩存;

整個(gè)流程操作下來(lái)發(fā)現(xiàn)數(shù)據(jù)庫(kù)age為20,緩存age為18,即數(shù)據(jù)庫(kù)與緩存不一致,導(dǎo)致應(yīng)用程序從緩存中讀到的數(shù)據(jù)都為舊數(shù)據(jù)。

但我們仔細(xì)想一下,上述問(wèn)題發(fā)生的概率其實(shí)非常低,因?yàn)橥ǔ?shù)據(jù)庫(kù)更新操作比內(nèi)存操作耗時(shí)多出幾個(gè)數(shù)量級(jí),上圖中最后一步回寫(xiě)緩存(set age 18)速度非???,通常會(huì)在更新數(shù)據(jù)庫(kù)之前完成。

如果這種極端場(chǎng)景出現(xiàn)了怎么辦?我們得想一個(gè)兜底的辦法:緩存數(shù)據(jù)設(shè)置過(guò)期時(shí)間。通常在系統(tǒng)中是可以允許少量的數(shù)據(jù)短時(shí)間不一致的場(chǎng)景出現(xiàn)。

Read through

在 Cache Aside 更新模式中,應(yīng)用代碼需要維護(hù)兩個(gè)數(shù)據(jù)源頭:一個(gè)是緩存,一個(gè)是數(shù)據(jù)庫(kù)。而在 Read-Through 策略下,應(yīng)用程序無(wú)需管理緩存和數(shù)據(jù)庫(kù),只需要將數(shù)據(jù)庫(kù)的同步委托給緩存提供程序 Cache Provider 即可。所有數(shù)據(jù)交互都是通過(guò)抽象緩存層完成的。

Read-Through流程

如上圖,應(yīng)用程序只需要與Cache Provider交互,不用關(guān)心是從緩存取還是數(shù)據(jù)庫(kù)。

在進(jìn)行大量讀取時(shí),Read-Through 可以減少數(shù)據(jù)源上的負(fù)載,也對(duì)緩存服務(wù)的故障具備一定的彈性。如果緩存服務(wù)掛了,則緩存提供程序仍然可以通過(guò)直接轉(zhuǎn)到數(shù)據(jù)源來(lái)進(jìn)行操作。

Read-Through 適用于多次請(qǐng)求相同數(shù)據(jù)的場(chǎng)景,這與 Cache-Aside 策略非常相似,但是二者還是存在一些差別,這里再次強(qiáng)調(diào)一下:

  • 在 Cache-Aside 中,應(yīng)用程序負(fù)責(zé)從數(shù)據(jù)源中獲取數(shù)據(jù)并更新到緩存。
  • 在 Read-Through 中,此邏輯通常是由獨(dú)立的緩存提供程序(Cache Provider)支持。

Write through

Write-Through 策略下,當(dāng)發(fā)生數(shù)據(jù)更新(Write)時(shí),緩存提供程序 Cache Provider 負(fù)責(zé)更新底層數(shù)據(jù)源和緩存。

緩存與數(shù)據(jù)源保持一致,并且寫(xiě)入時(shí)始終通過(guò)抽象緩存層到達(dá)數(shù)據(jù)源。

Cache Provider類似一個(gè)代理的作用。

Write-Through流程

Write behind

Write behind在一些地方也被成為Write back, 簡(jiǎn)單理解就是:應(yīng)用程序更新數(shù)據(jù)時(shí)只更新緩存, Cache Provider每隔一段時(shí)間將數(shù)據(jù)刷新到數(shù)據(jù)庫(kù)中。說(shuō)白了就是延遲寫(xiě)入。

Write behind流程

如上圖,應(yīng)用程序更新兩個(gè)數(shù)據(jù),Cache Provider 會(huì)立即寫(xiě)入緩存中,但是隔一段時(shí)間才會(huì)批量寫(xiě)入數(shù)據(jù)庫(kù)中。

這種方式有優(yōu)點(diǎn)也有缺點(diǎn):

  • 優(yōu)點(diǎn)是數(shù)據(jù)寫(xiě)入速度非???,適用于頻繁寫(xiě)的場(chǎng)景。
  • 缺點(diǎn)是緩存和數(shù)據(jù)庫(kù)不是強(qiáng)一致性,對(duì)一致性要求高的系統(tǒng)慎用。

總結(jié)

學(xué)了這么多,相信大家對(duì)緩存更新的策略都已經(jīng)有了清晰的認(rèn)識(shí)。最后稍稍總結(jié)一下。

緩存更新的策略主要分為三種:

  • Cache aside
  • Read/Write through
  • Write behind

Cache aside 通常會(huì)先更新數(shù)據(jù)庫(kù),然后再刪除緩存,為了兜底通常還會(huì)將數(shù)據(jù)設(shè)置緩存時(shí)間。

Read/Write through 一般是由一個(gè) Cache Provider 對(duì)外提供讀寫(xiě)操作,應(yīng)用程序不用感知操作的是緩存還是數(shù)據(jù)庫(kù)。

Write behind簡(jiǎn)單理解就是延遲寫(xiě)入,Cache Provider 每隔一段時(shí)間會(huì)批量輸入數(shù)據(jù)庫(kù),優(yōu)點(diǎn)是應(yīng)用程序?qū)懭胨俣确浅?臁?/p>

好了,今天先到這里了,大家學(xué)會(huì)了嗎?

責(zé)任編輯:武曉燕 來(lái)源: 愛(ài)笑的架構(gòu)師
相關(guān)推薦

2021-03-19 07:40:22

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

2024-12-16 08:01:57

2023-12-27 13:44:00

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

2019-12-24 09:12:10

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

2018-07-13 15:56:39

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

2021-01-29 10:51:48

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

2011-03-07 17:11:21

云遷移云轉(zhuǎn)型

2018-07-06 15:04:24

緩存token線程

2024-02-01 09:51:17

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

2024-08-20 08:19:43

2018-07-27 10:56:10

2022-10-11 10:18:12

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

2024-03-05 10:03:17

NoSQL數(shù)據(jù)庫(kù)算法

2024-03-14 08:57:04

高并發(fā)緩存更新

2025-02-16 23:15:17

2021-08-06 22:47:37

編程語(yǔ)言數(shù)據(jù)工具

2020-09-04 06:32:08

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

2011-07-01 14:03:44

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

2009-12-22 17:24:22

ADO.NET數(shù)據(jù)庫(kù)

2024-12-26 15:01:29

點(diǎn)贊
收藏

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