緩存與資料庫雙寫一致性幾種策略分析

来源:https://www.cnblogs.com/jingdongkeji/archive/2023/04/19/17333646.html
-Advertisement-
Play Games

本文將對幾種緩存與資料庫保證數據一致性的使用方式進行分析。為保證高併發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ...


作者:京東零售 於瀧

一、背景

在高併發場景中,為防止大量請求直接訪問資料庫,緩解資料庫壓力,常用的方式一般會增加緩存層起到緩衝作用,減少資料庫壓力。引入緩存,就會涉及到緩存與資料庫中數據如何保持一致性問題,本文將對幾種緩存與資料庫保證數據一致性的使用方式進行分析。為保證高併發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。

二、讀取過程

• 讀緩存

• 如果緩存里沒有值,那就讀取資料庫的值

• 同時把這個值寫進緩存中

三、更新過程

更新操作有多種策略,各有優劣,主要針對此場景進行分析

策略1:先更新db,再刪除緩存(常用的Cache-Aside Pattern旁路緩存)

問題:

1.如果更新db成功,刪緩存失敗,將導致數據不一致

2.極端場景,請求A讀,B寫

1)此時緩存剛好失效 2)A查庫得到舊值 3)B更新DB成功

4)B刪除緩存 5)A將查到的舊值更新到緩存中

此場景的發生需要步驟2)查db 始終慢於 3)的更新db,才能導致4)先於5)執行,通常db的查詢是要快於寫入的,所以此極端場景的產生過於嚴格,不易發生

策略2:先更新db,再更新緩存

問題:

1.併發更新場景下,更新緩存會導致數據不一致

2.根據讀寫比,考慮是否有必要頻繁同步更新緩存,而且,如果構造緩存中數據過於複雜,或者數據更新頻繁,但是讀取並不頻繁的情況,還會造成不必要的性能損耗

此種方式不推薦

策略3:先更新緩存,再更新db

同上,不推薦

策略4:先刪緩存,再更新db

先刪緩存,雖然解決了策略1中,後刪緩存如果失敗的場景,但也會發生不一致的問題

例如:請求 A 刪除緩存,這時請求B來查,就會擊穿到資料庫,B讀取到舊的值後寫入緩存,A正常更新db,由於時間差導致數據不一致的情況

策略5:緩存延時雙刪

該策略相容了策略1和策略4,解決了先刪緩存還是後刪緩存的問題,如策略1中,更新db後刪緩存失敗和策略4中的不一致場景,該策略可以將延時時間內(比如延時10ms)所造成的緩存臟數據,再次刪除。但是,如果延時刪緩存失敗,策略4中不一致問題還會發生,同時延時的實現,如創建線程,或者引入mq非同步,可能會增加系統複雜度問題。

策略6:變種雙刪,前置緩存過期時間

該策略針對策略1中後刪緩存失敗的場景,前置一層緩存數據過期時間(具體時間根據自身系統本身評估,如可覆蓋db讀寫耗時或一致性容忍度等),更新db後就算刪緩存失敗,在expire時間後也能保證緩存中無數據。同時,前置expire失敗,或者更新db失敗,都不會影響數據一致。

能夠解決策略4中的問題:請求 A 刪除緩存,這時請求B來查,就會擊穿到資料庫,B讀取到舊的值後寫入緩存,A正常更新db,由於時間差導致數據不一致的情況,描述圖如下:

本策略中步驟1為expire緩存,不會發生擊穿緩存到資料庫的情況,數據將直接返回。除非更極端情況,如下圖:

expire時間沒有覆蓋住更新db的耗時,類似策略1中極端場景,此處不贅述

四、總結

對於每種方案策略,各有利弊,但一致性問題始終存在(文章開頭排除了原子性和鎖),只是發生的幾率在一點點慢慢變小了,方案的評估不僅要根據自身系統的業務場景,如讀寫比、併發量、一致性容忍度,還要考慮系統複雜度,投入產出比等,尋找最合適的方案。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在運行 Linux 系統的過程中為了讓電腦或者伺服器以最佳水平運行,常常需要監控記憶體統計信息。今天我們就來看看都有那些方法可以查看記憶體信息。 ...
  • 報錯如下 [root@centos bin]# ./redis-server ./redis-server: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such fi ...
  • VMware17安裝Windows10詳細記錄 1. 前置準備 VMware軟體,這裡用的VMware17 Windows系統鏡像文件(.iso文件) Windows系統官方下載地址:Windows系統官方下載 I Tell You舊版站點:MSDN, 我告訴你 - 做一個安靜的工具站 (itell ...
  • 簡介:由於資源有限,本實驗用了兩台機器 監控端:部署prometheus、grafana、alertmanager 被監控端:node_exporter、mysqld_exporter 一. 部署promethus 1. 下載 https://prometheus.io/download/ 2. 解 ...
  • 0.linux的目錄結構 1.用戶和用戶組的信息存儲 1.1. 用戶的基本信息文件/etc/passwd 1.1.1. 用戶名 1.1.2. 密碼 1.1.3. UID 1.1.4. GID 1.1.5. 註釋性描述 1.1.6. 宿主目錄 1.1.7. 預設shell 1.2. 用戶的密碼信息文件 ...
  • 功能02-商鋪查詢緩存 3.商鋪詳情緩存查詢 3.1什麼是緩存? 緩存就是數據交換的緩衝區(稱作Cache),是存儲數據的臨時地方,一般讀寫性能較高。 緩存的作用: 降低後端負載 提高讀寫效率,降低響應時間 緩存的成本: 數據一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ...
  • 關於MySQL的二進位日誌(binlog),我們都知道二進位日誌(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關於二進位日誌(binlog)的備份,可以基於flush logs方式先切換binlog,然後拷貝&壓縮到到遠程伺服器或本地伺服器 ...
  • 功能實現02 2.功能01-簡訊登錄 2.1基於Session實現登錄 2.1.1思路分析 2.1.2代碼實現 2.1.2.1發送簡訊驗證碼 發送簡訊驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...