亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

MySQL與Redis如何保證雙寫一致性詳解

 更新時間:2025年10月29日 11:29:21   作者:程序員小假  
雙寫一致性是指在系統(tǒng)中同時使用緩存(如Redis)和數(shù)據(jù)庫(如MySQL)時,如何確保兩者的數(shù)據(jù)保持一致,這篇文章主要介紹了MySQL與Redis如何保證雙寫一致性的相關資料,需要的朋友可以參考下

前言

首先,我們必須明確一個核心觀點:在分布式環(huán)境下,要實現(xiàn)強一致性(在任何時刻讀取的數(shù)據(jù)都是最新的)是極其困難且代價高昂的,通常會嚴重犧牲性能。因此,在實踐中,我們通常追求最終一致性,即允許在短暫的時間內數(shù)據(jù)不一致,但通過一些手段保證數(shù)據(jù)最終會保持一致。

下面我將從基礎概念、各種策略、最佳實踐到最新方案,為你詳細講解。

一、基礎概念:為什么會有不一致?

在一個包含 MySQL(作為可靠數(shù)據(jù)源)和 Redis(作為緩存)的系統(tǒng)中,所有的寫操作(增、刪、改)都必須同時處理這兩個地方。

這個過程中,任何一步失敗或延遲都會導致不一致:

  1. 寫 MySQL 成功,寫 Redis 失敗:導致 Redis 中是舊數(shù)據(jù)。
  2. 寫 Redis 成功,寫 MySQL 失敗:導致 Redis 中是“臟數(shù)據(jù)”,數(shù)據(jù)庫中不存在。
  3. 并發(fā)讀寫:一個線程在更新數(shù)據(jù)庫,但還沒更新緩存時,另一個線程讀取了舊的緩存數(shù)據(jù)。

二、核心策略與模式

解決雙寫一致性有多種策略,我們需要根據(jù)業(yè)務場景(對一致性的要求、讀寫的比例等)進行選擇。

策略一:Cache-Aside Pattern(旁路緩存模式)

這是最常用、最經(jīng)典的緩存模式。核心原則是:應用程序直接與數(shù)據(jù)庫和緩存交互,緩存不作為寫入的必經(jīng)之路。

  • 讀流程
    1. 收到讀請求。
    2. 首先查詢 Redis,如果數(shù)據(jù)存在(緩存命中),直接返回。
    3. 如果 Redis 中沒有數(shù)據(jù)(緩存未命中),則從 MySQL 中查詢。
    4. 將從 MySQL 查詢到的數(shù)據(jù)寫入 Redis(以便后續(xù)讀?。缓蠓祷財?shù)據(jù)。
  • 寫流程
    1. 收到寫請求。
    2. 更新 MySQL 中的數(shù)據(jù)。
    3. 刪除 Redis 中對應的緩存。

為什么是刪除(Invalidate)緩存,而不是更新緩存?
這是一個關鍵設計點!

  • 性能:如果更新緩存,每次數(shù)據(jù)庫寫操作都要伴隨一次緩存寫操作,如果該數(shù)據(jù)并不經(jīng)常被讀取,那么這次緩存寫入就是浪費資源的。
  • 并發(fā)安全:在并發(fā)寫場景下,更新緩存的順序可能與更新數(shù)據(jù)庫的順序不一致,導致緩存中是舊數(shù)據(jù)。而刪除操作是冪等的,更為安全。

Cache-Aside 如何保證一致性?
它通過“先更新數(shù)據(jù)庫,再刪除緩存”來盡力保證。但它依然存在不一致的窗口期:

  1. 線程 A 更新數(shù)據(jù)庫。
  2. 線程 B 讀取數(shù)據(jù),發(fā)現(xiàn)緩存不存在,從數(shù)據(jù)庫讀取舊數(shù)據(jù)(因為 A 還沒提交或剛提交)。
  3. 線程 B 將舊數(shù)據(jù)寫入緩存。
  4. 線程 A 刪除緩存。

這種情況發(fā)生的概率較低,因為通常數(shù)據(jù)庫寫操作(步驟1)會比讀操作(步驟2)耗時更長(因為涉及鎖、日志等),所以步驟2在步驟1之前完成的概率很小。但這是一種理論上的可能。

策略二:Write-Through / Read-Through Pattern(穿透讀寫模式)

在這種模式下,緩存層(或一個獨立的服務)自己負責與數(shù)據(jù)庫交互。對應用來說,它只與緩存交互。

  • 寫流程:應用寫入緩存,緩存組件同步地寫入數(shù)據(jù)庫。只有兩個都成功后才會返回成功。
  • 讀流程:應用讀取緩存,如果未命中,緩存組件自己從數(shù)據(jù)庫加載并填充緩存,然后返回。

優(yōu)點:邏輯對應用透明,一致性比 Cache-Aside 更好。
缺點:性能較差,因為每次寫操作都必然涉及一次數(shù)據(jù)庫寫入。通常需要成熟的緩存中間件支持。

策略三:Write-Behind Pattern(異步寫回模式)

Write-Through 的異步版本。應用寫入緩存后立即返回,緩存組件在之后某個時間點(例如攢夠一批數(shù)據(jù)或定時)批量異步地更新到數(shù)據(jù)庫。

優(yōu)點:寫性能極高。
缺點:有數(shù)據(jù)丟失風險(緩存宕機),一致性最弱。適用于允許少量數(shù)據(jù)丟失的場景,如計數(shù)、點贊等。

三、保證最終一致性的進階方案

為了彌補 Cache-Aside 模式中的缺陷,我們可以引入一些額外的機制。

方案一:延遲雙刪

針對 Cache-Aside 中提到的“先更新數(shù)據(jù)庫,再刪除緩存”可能帶來的并發(fā)問題,可以引入一個延遲刪除。

  1. 線程 A 更新數(shù)據(jù)庫。
  2. 線程 A 刪除緩存。
  3. 線程 A 休眠一個特定的時間(如 500ms - 1s)。
  4. 線程 A 再次刪除緩存。

第二次刪除是為了清理掉在第1次刪除后、其他線程可能寫入的舊數(shù)據(jù)。這個休眠時間需要根據(jù)業(yè)務讀寫耗時來估算。

優(yōu)點:簡單有效,能很大程度上解決并發(fā)讀寫導致的不一致。
缺點:降低了寫入吞吐量,休眠時間難以精確設定。

方案二:通過消息隊列異步刪除

為了解耦和重試,可以將刪除緩存的操作作為消息發(fā)送到消息隊列(如 RocketMQ, Kafka)。

  1. 更新數(shù)據(jù)庫。
  2. 向消息隊列發(fā)送一條刪除緩存的消息。
  3. 消費者消費該消息,執(zhí)行刪除 Redis 的操作。如果刪除失敗,消息會重試。

這保證了刪除緩存的操作至少會被執(zhí)行一次,大大提高了可靠性。

方案三:通過數(shù)據(jù)庫 Binlog 同步(最優(yōu)解)

這是目前最成熟、對業(yè)務侵入性最小、一致性最好的方案。其核心是利用 MySQL 的二進制日志(Binlog)進行增量數(shù)據(jù)同步。

工作原理

  1. 業(yè)務系統(tǒng)正常寫入 MySQL。
  2. 由一個中間件(如 Canal, Debezium)偽裝成 MySQL 的從庫,訂閱 Binlog。
  3. 中間件解析 Binlog,獲取數(shù)據(jù)的變更詳情(增、刪、改)。
  4. 中間件根據(jù)變更,調用 Redis 的 API 來更新或刪除對應的緩存。

優(yōu)點

  • 業(yè)務無侵入:業(yè)務代碼只關心寫數(shù)據(jù)庫,完全不知道緩存的存在。
  • 高性能:數(shù)據(jù)庫和緩存的同步是異步的,不影響主業(yè)務鏈路的性能。
  • 強保證:由于基于 Binlog,它能保證只要數(shù)據(jù)庫變了,緩存最終一定會被同步。順序也與數(shù)據(jù)庫一致。

缺點

  • 架構復雜,需要維護額外的同步組件。
  • 同步有毫秒級到秒級的延遲。

四、總結與最佳實踐選擇

策略

一致性保證

性能

復雜度

適用場景

Cache-Aside + 刪除

最終一致性(有微弱不一致風險)

絕大多數(shù)場景的首選,讀多寫少

Cache-Aside + 延遲雙刪

更好的最終一致性

對一致性要求稍高,且能接受一定延遲的寫操作

Write-Through

強一致性

寫多讀少,且對一致性要求非常高的場景

Binlog 同步

最終一致性(推薦)

大型、高要求項目的最佳實踐,對業(yè)務無侵入

通用建議

  1. 首選方案:對于大多數(shù)應用,從 Cache-Aside(先更新數(shù)據(jù)庫,再刪除緩存) 開始。它簡單、有效,在大多數(shù)情況下已經(jīng)足夠。
  2. 進階保障:如果 Cache-Aside 的不一致窗口無法接受,可以引入延遲雙刪消息隊列異步刪除來增強。
  3. 終極方案:當業(yè)務發(fā)展到一定規(guī)模,對一致性和系統(tǒng)解耦有更高要求時,投入資源搭建基于 Binlog 的異步同步方案。這是業(yè)界證明最可靠的方案。
  4. 設置合理的過期時間:無論如何,都給 Redis 中的緩存設置一個過期時間(TTL)。這是一個安全網(wǎng),即使同步邏輯出現(xiàn)問題,舊數(shù)據(jù)也會自動失效,最終從數(shù)據(jù)庫加載新數(shù)據(jù),保證最終一致性。
  5. 業(yè)務容忍度:最重要的是,與產品經(jīng)理確認業(yè)務對一致性的容忍度。很多時候,1-2秒內的數(shù)據(jù)不一致用戶是感知不到的,不需要為此付出巨大的架構和性能代價。

總結

到此這篇關于MySQL與Redis如何保證雙寫一致性的文章就介紹到這了,更多相關MySQL與Redis保證雙寫一致性內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • MySQL執(zhí)行過程中選擇最佳的執(zhí)行路徑的方法(核心流程)

    MySQL執(zhí)行過程中選擇最佳的執(zhí)行路徑的方法(核心流程)

    文章介紹MySQL查詢優(yōu)化器如何通過解析、生成執(zhí)行計劃及成本評估選擇最佳路徑,依賴統(tǒng)計信息如表行數(shù)和索引基數(shù),開發(fā)者需創(chuàng)建索引、更新統(tǒng)計信息、優(yōu)化SQL寫法及使用EXPLAIN工具輔助優(yōu)化,感興趣的朋友跟隨小編一起看看吧
    2025-09-09
  • 一文帶你了解MySQL之InnoDB統(tǒng)計數(shù)據(jù)是如何收集的

    一文帶你了解MySQL之InnoDB統(tǒng)計數(shù)據(jù)是如何收集的

    通過show index可以看到關于索引的統(tǒng)計數(shù)據(jù),那么這些統(tǒng)計數(shù)據(jù)是怎么來的呢,它們是以什么方式收集的呢,本章將聚焦于InnoDB存儲引擎的統(tǒng)計數(shù)據(jù)收集策略,需要的朋友可以參考下
    2023-05-05
  • Windows7下安裝使用MySQL8.0.16修改密碼、連接Navicat問題

    Windows7下安裝使用MySQL8.0.16修改密碼、連接Navicat問題

    這篇文章主要介紹了Windows7下安裝使用MySQL8.0.16修改密碼、連接Navicat問題,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-06-06
  • MySQL是如何保證數(shù)據(jù)的完整性

    MySQL是如何保證數(shù)據(jù)的完整性

    這篇文章主要介紹了MySQL是如何保證數(shù)據(jù)的完整性,幫助大家更好的理解和學習MySQL,感興趣的朋友可以了解下
    2020-08-08
  • MySQL流程控制函數(shù)匯總分析講解

    MySQL流程控制函數(shù)匯總分析講解

    MySQL流程控制函數(shù)包括if、case、while、repeat、loop、leave、iterate等,可以在SQL語句中實現(xiàn)條件判斷、循環(huán)、跳出等功能,提高了SQL語句的靈活性和功能性
    2023-04-04
  • MySQL在右表數(shù)據(jù)不唯一的情況下使用left join的方法

    MySQL在右表數(shù)據(jù)不唯一的情況下使用left join的方法

    這篇文章主要介紹了MySQL在右表數(shù)據(jù)不唯一的情況下使用left join的方法,針對右表符合條件表達式的記錄數(shù)大于1條時left join所顯示的結果需求來講,需要的朋友可以參考下
    2016-03-03
  • 一文搞懂MySQL索引所有知識點

    一文搞懂MySQL索引所有知識點

    這篇文章主要帶你搞懂MySQL索引的所有知識點,我們通常所說的索引,包括聚焦索引、覆蓋索引、組合索引、前綴索引、唯一索引等,沒有特別說明,默認都是使用B+樹結構組織,感興趣的小伙伴可以參考閱讀
    2023-03-03
  • 解決當MySQL數(shù)據(jù)庫遇到Syn Flooding問題

    解決當MySQL數(shù)據(jù)庫遇到Syn Flooding問題

    Syn攻擊常見于應用服務器,而數(shù)據(jù)庫服務器在內網(wǎng)中,應該很難碰到類似的攻擊,這篇文章主要介紹了當MySQL數(shù)據(jù)庫遇到Syn Flooding問題 ,需要的朋友可以參考下
    2019-06-06
  • MySQL8 全文索引的實現(xiàn)方法

    MySQL8 全文索引的實現(xiàn)方法

    MySQL8支持全文索引和全文搜索,本文主要介紹了MySQL8全文索引的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-08-08
  • MySQL非常重要的日志bin log詳解

    MySQL非常重要的日志bin log詳解

    bin log想必大家多多少少都有聽過,它是MySQL中一個非常重要的日志,因為它涉及到數(shù)據(jù)庫層面的主從復制、高可用等設計,所以本文就給大家詳細的講解MySQL非常重要的日志—bin log,需要的朋友可以參考下
    2023-07-07

最新評論