1. 程式人生 > >K:快取資料庫雙寫資料一致性方案

K:快取資料庫雙寫資料一致性方案

對於快取和資料庫雙寫,其存在著資料一致性的問題。對於資料一致性要求較高的業務場景,我們通常會選擇使用分散式事務(2pc、paxos等)來保證快取與資料庫之間的資料強一致性,但分散式事務的複雜性與對資源的佔用問題,使得該處理方式會造成系統性能的降低。對於資料一致性要求沒那麼高的業務場景,選擇分散式事務的處理方式就會顯得不是那麼必要。為此,在一般情況下,對於資料一致性要求沒那麼高的業務場景,會選擇使用cache-aside-pattern方案來保證快取與資料庫之間,資料的最終一致性,以下文章便是介紹並整理該cache-aside-pattern方案的內容。

對於快取中的資料,我們提出三個目標:

  1. 儘可能不將資料庫中的舊資料存入快取中
  2. 允許快取中的資料與資料庫中的資料存在一小段時間的不一致
  3. 快取中的資料與資料庫中的資料存在資料不一致的時間應儘量短

對於快取與資料庫的雙寫問題,無外乎“增刪改查” 這四個過程,再考慮進併發的“讀讀,寫寫,讀寫”情況,所有可能的情況組合並不多。為此,我們可以採用窮舉的方式對該方案進行說明。

查:

對於資料的查詢,該方案的過程與cpu中查詢資料的過程是一致的,其過程如下:

  1. 先查詢快取中的資料,當命中快取的時候返回資料,查詢結束。
  2. 當沒有命中快取時,查詢資料庫,對資料庫中查找出的相關資料進行處理,之後將相關的資料存入快取中,查詢結束。

其示意圖如下:

在考慮高併發查詢的情況下,對於該處理過程,如下示意圖所示。

當客戶端1、客戶端2、....、客戶端n查詢同一資料,且該資料不存在於快取中時,所有的客戶端請求都會去訪問資料庫,此時會出現快取擊穿的情況,對於快取擊穿的相關問題及解決方案,我們留到下一篇文章再進行講解。

增:

對於新增資料的情況,我們將資料直接新增進資料庫中,且不將新增的資料載入入快取中,其過程如下示意圖所示:

在考慮高併發之時,其過程如下示意圖所示:

通過示意圖,我們瞭解到,當採用該種方式新增資料時,在併發情況下,並未出現與我們的目標相違背的問題。

刪:

當需要對資料進行刪除時,我們有兩種刪除的方案可供選擇。

第一種: 先刪除快取中的資料,再刪除資料庫中的資料

第二種: 先刪除資料庫中的資料,再刪除快取中的資料

我們對這兩種方案分別進行分析:

先刪快取:

對於先刪除快取中的資料,後刪除資料庫中的資料這種方案,其示意圖如下:

考慮進高併發的情況,當存在讀請求和刪除資料的請求併發時,由於網路的不可靠和延時問題,其可能出現如下示意圖所示的情況:

通過示意圖我們瞭解到,存在著快取中快取進已刪除的舊資料的情況,這違背了我們提出的第一個目標。

那麼,先刪除資料庫中的資料的情況呢?會出現這樣的問題嗎?我們接著分析。

先刪資料庫:

對於先刪除資料庫中的資料,後刪除快取中的資料這種方案,其示意圖如下。

同樣考慮進高併發的情況,當存在讀請求和刪除資料的請求併發時,其發生的情況如下示意圖所示:

此時,並未出現與我們的目標相違背的問題。綜上,我們在刪除資料時,應選擇先刪除資料庫中的資料再刪除快取中的資料的這一方案。

但是該方案仍存在著問題。我們再往下思考,當刪除了快取中的相關資料,此時來了大量讀取該資料的請求。這時,就會導致“快取穿透”問題的出現(該問題同樣在下一篇文章中進行講解)。

改:

當需要對資料進行變更的時候,我們有三種方案可供選擇。

第一種: 先更新資料庫,後更新快取

第二種: 先刪除快取,後更新資料庫

第三種: 先更新資料庫,後刪除快取

我們對這三種方案逐一進行分析。

先更新資料庫,後更新快取:

對於先更新資料庫,後更新快取這種方案,其示意圖如下:

考慮高併發的情況,當存在兩個更新操作的併發請求時,由於網路的延時問題,其可能會出現如下這種情況:

由上述示意圖可知,當存在兩個更新操作時,其有將資料庫中的舊資料存入快取中的情況,這違背了我們的第一個目標。那麼,有沒有辦法解決呢?答案是有的,藉助樂觀鎖的相關思想,我們可以給每個資料加上一個版本號,當資料要存入快取時,比較一下資料的版本號即可。到目前為止,更新了資料庫中的相關資料之後,再更新快取中的資料這個方案看起來是可以的,但是這個方案存在著一個問題,就是需要去更新快取中的資料,更新快取中的資料這個操作會影響系統的效能。特別是在寫多讀少,且快取的資料不是直接從資料庫中存入,而是經過計算之後再進行快取的業務場景中時,對系統性能造成的影響會更加明顯。為此我們可以藉助“懶載入”的思想,在更新資料之時,將快取中的資料進行刪除,等到需要用到的時候,才將資料載入進快取中。下面我們將討論在更新時刪除快取的兩個可能的方案。

先刪除快取,後更新資料庫:

對於先刪除快取,後更新資料庫的方案,其示意圖如下:

考慮高併發的情況,當存在讀請求和更新請求併發的情況,由於存在網路延時,其可能出現如下示意圖中的情況:

由示意圖中的情況可知,在讀寫併發的情況下,其存在著將資料庫中的舊資料存入快取中的問題。這違背了我們的第一個目標。

先更新資料庫,後刪除快取:

對於先更新資料庫,後刪除快取的情況,其如下示意圖所示:

考慮併發的情況,當存在讀請求和更新請求併發,且此時快取中的資料恰好失效時,再加上由於網路的延遲問題,則有可能會出現如下示意圖所示的情況。

由示意圖可知,當快取中的資料恰好失效時,其是可能存在著快取中存入資料庫中的舊資料的可能性的。但是,發生這種情況的概率是比較低的,因為讓該種情況出現的條件較為“苛刻”,需要恰好快取中的資料失效,且要求“讀操作”慢於“寫操作”。但在通常情況下,“寫操作”是慢於“讀操作”的,因為寫操作一般會涉及到資料庫鎖的相關操作。
綜上,在對比了以上三種方案之後,對於資料更改的情況,我們採用先更新資料庫,後刪除快取的方式。


相關推薦

K快取資料庫資料一致性方案

對於快取和資料庫雙寫,其存在著資料一致性的問題。對於資料一致性要求較高的業務場景,我們通常會選擇使用分散式事務(2pc、paxos等)來保證快取與資料庫之間的資料強一致性,但分散式事務的複雜性與對資源的佔用問題,使得該處理方式會造成系統性能的降低。對於資料一致性要求沒那麼高的業務場景,選擇分散式事務的處理方式

高併發快取+資料庫不一致

高併發快取+資料庫雙寫不一致 最初快取不一致 情景一 先修改資料庫,再刪除快取,如果刪除快取失敗了,那麼會導致資料庫中是新資料,快取中是舊資料,資料出現不一致 解決方案 先刪除快取,再修改資料庫,如果刪除快取成功了,如果修改資料庫失敗了,那麼資料

高併發場景下的快取+資料庫不一致問題分析與解決方案

1、最初級的快取不一致問題以及解決方案問題:先修改資料庫,再刪除快取,如果刪除快取失敗了,那麼會導致資料庫中是新資料,快取中是舊資料,資料出現不一致。解決思路:先刪除快取,再修改資料庫,如果刪除快取成功了,如果修改資料庫失敗了,那麼資料庫中是舊資料,快取中是空的,那麼資料不會

高併發場景下的快取 資料庫不一致問題分析與解決方案設計

馬上開始去開發業務系統 從哪一步開始做,從比較簡單的那一塊開始做,實時性要求比較高的那塊資料的快取去做 實時性比較高的資料快取,選擇的就是庫存的服務 庫存可能會修改,每次修改都要去更新這個快取資料; 每次庫存的資料,在快取中一旦過期,或者是被清理掉了,前端的ngin

25-02、高併發場景下的快取+資料庫不一致問題分析與解決方案設計

馬上開始去開發業務系統, 從哪一步開始做,從比較簡單的那一塊開始做,實時性要求比較高的那塊資料的快取去做, 實時性比較高的資料快取,選擇的就是庫存的服務, 庫存可能會修改,每次修改都要去更新這個快取資料; 每次庫存的資料,在快取中一旦過期,或者是被清理掉了,前端的nginx服務都會發送請

高併發場景下快取+資料庫不一致問題分析與解決方案設計

能堅持別人不能堅持的,才能擁有別人不能擁有的。   文章首發於左上角公眾號,同步到部落格園會延遲一到兩天。 關注程式設計大道公眾號,讓我們一同堅持心中所想,一起成長!! Redis是企業級系統高併發、高可用架構中非常重要的一個環節。Redis主要解決了關係型資料庫併發量低的問題,有助於緩

25、如何保證快取資料庫時的資料一致性

1、面試題 如何保證快取與資料庫的雙寫一致性? 2、面試官心裡分析 你只要用快取,就可能會涉及到快取與資料庫雙儲存雙寫,你只要是雙寫,就一定會有資料一致性的問題,那麼你如何解決一致性問題? 3、面試題剖析 一般來說,就是如果你的系統不是嚴格要求快取+資料庫必須一致性的話,快取可以

Redis快取資料庫一致性問題:

    資料庫與快取讀寫模式策略   寫完資料庫後是否需要馬上更新快取還是直接刪除快取?   (1)、如果寫資料庫的值與更新到快取值是一樣的,不需要經過任何的計算,可以馬上更新快取,但是如果對於那種寫資料頻繁而讀資料少的場景並不合適這種解決方

Redis使用總結(二、快取資料庫一致性問題)

首先,快取由於其高併發和高效能的特性,已經在專案中被廣泛使用。在讀取快取方面,大家沒啥疑問,都是按照下圖的流程來進行業務操作。但是在更新快取方面,對於更新完資料庫,是更新快取呢,還是刪除快取。又或者是先刪除快取,再更新資料庫,其實大家存在很大的爭議。目前沒有一篇全面的部落格,

淺析資料庫快取一致性問題

快取由於其高併發和高效能的特性,在專案中被廣泛使用。讀快取流程如下圖: 雙寫一致性有以下三個要求: 快取不能讀到髒資料 快取可能會讀到過期資料,但要在可容忍時間內實現最終一致 這個可容忍時間儘可能的小 要想同時滿足上面三條,可以採用讀請求和寫請求序列化,串到一個記憶體佇列裡去,這樣就可以保證一定不會出

快取資料庫一致性 深度分析

# 前言 微笑挖坑,努力填坑。         ———— 已經擁有黑眼圈,但還沒學會小豬老師時間管理學的蠻三刀同學 我們來討論秒殺系統中**快取熱點資料**的問題,進一步延伸到資料庫和快取的雙寫一致性問題,並且給出了實現程式碼。 ## 本篇文章主要內容 - 快取熱點資料 - 為何要使用

redis和資料庫一致性問題

   一致性問題是分散式常見問題,還可以再分為最終一致性和強一致性。資料庫和快取雙寫,就必然會存在不一致的問題。答這個問題,先明白一個前提。就是如果對資料有強一致性要求,不能放快取。我們所做的一切,只能保證最終一致性。     從理論上來說,給快取設定過期時間,是保證最終一

高併發架構系列Redis快取和MySQL資料一致性方案詳解

一、需求起因 在高併發的業務場景下,資料庫大多數情況都是使用者併發訪問最薄弱的環節。所以,就需要使用redis做一個緩衝操作,讓請求先訪問到redis,而不是直接訪問MySQL等資料庫。 這個業務場景,主要是解決讀資料從Redis快取,一般都是按照下圖的流程來進行業務操作。 讀取快取步驟

快取資料庫,不一致問題及解決方案

面試題 如何保證快取與資料庫的雙寫一致性? 面試官心理分析 你只要用快取,就可能會涉及到快取與資料庫雙儲存雙寫,你只要是

併發中如何保證快取DB一致性(JAVA栗子)

  併發場景中大部分處理的是先更新DB,再(刪緩、更新)快取的處理方式,但是在實際場景中有可能DB更新成功了,但是快取設定失敗了,就造成了快取與DB資料不一致的問題,下面就以實際情況說下怎麼解決此類問題。   名詞 Cache:本文內指redis,ReadRequest:請求從Cache、Db中拿去資料,Wr

《SQL入門經典》筆記(第五章建立資料庫之操作資料

1. 資料操作語言(DML),用於修改關係型資料庫裡的資料和表。   2. SQL中三個基本的DML命令是: INSERT UPDATE DELETE SELECT(基本查詢命令)可以與DML配合使用。   3. INSERT:

第三篇快取資料庫Redis

快取資料庫的介紹請百度 學習資料 本文主要使用Redis製作簡單的使用者賬戶和排行榜 先看一個圖 這裡是Redis不同資料型別 應用的不同場景,再根據我們的要求,我們選擇了 賬戶使用 Hash 來進行儲存,排行榜使用 Sorted Set 進行儲存 賬戶儲存

微贊微擎V0.8以上版本資料庫分離】實戰教程 [複製連結]

http://www.efwww.com/forum.php?mod=viewthread&tid=4870   馬上註冊,下載更多原始碼,讓你輕鬆玩轉微信公眾平臺。 您需要 登入 才

1.Cache Asia Pattern (快取+資料庫模式)

Cache Asia Pattern (快取+資料庫讀寫模式) Cache Asia Pattern 讀流程:先讀快取,如果快取沒有資料,那麼讀取資料庫,然後取出資料放入快取,同時返回響應 寫流程:先刪除快取,然後更新資料庫 重點:為啥是刪除快取而不是更新

卜若的程式碼筆記系列-Web系列-SpringBoot-第十八章jdbc向sqlserver資料-3218

1.你通過十七章的學習學會了怎麼連線資料庫,現在教你怎麼向資料庫裡面寫資料 首先,你需要例項化一個JdbcTemplate物件 怎麼例項化呢,直接給該欄位加一個@Autowired的批註,就能夠例項化該物件,具體的我會放在第十九章講解 @Autowired     pr