redis 與 DB 的一致性 7 種策略

    • 為什么要使用 redis 做緩存?
      • 封底估算
          • 為什么是單行數據的QPS,而不是總的?
        • 什么時候使用DB,Redis,本地緩存
      • 數據的分類
      • 一致性的方案
        • 1. 先清除Redis,再更新 DB
        • 2. 先更新DB,再清除 Redis
          • 使用場景:
        • 3. 延遲刪除與延遲雙刪
          • 使用場景
        • 4. 監聽 binlog 清除
        • 5. 雙寫
          • 使用場景:
        • 6. 監聽binlog更新
        • 7.定時刷新
          • 使用場景
      • 選擇
      • 其他問題
        • 緩存穿透

為什么要使用 redis 做緩存?

高性能

  • redis壓力測試: 20w QPS(瓶頸是網絡 io)
  • MySQL: 2w QPS(瓶頸是磁盤io)

封底估算

是否使用緩存是有單行數據的 QPS 決定的

為什么是單行數據的QPS,而不是總的?
  • 使用(Redis)緩存主要是利用 緩存( Redis)高性能的特性減少DB的重復查詢
  • 就是數據需要多次查詢,并且每次查詢的結果是相同的,這時候加到緩存中,可以攔截大量的請求在緩存層,減少db的請求壓力
    舉個例子
  • 一些 IM 系統的總的 QPS 有幾十萬(qq,wx 這些)
  • 但是每個人接受的消息是不同的,并且消息是一次性消費的,所以針對單行消息而言,QPS 是小于 1 的并且是一次性消費,不涉及多次重復查詢,即使總的 QPS 非常高,也不會使用緩存(IM 系統會使用Redis,但是不是做緩存使用的)
什么時候使用DB,Redis,本地緩存

使用 DB

  • 當數據是部分人可見的(比如后臺管理/GM 的需求):單行數據的QPS<1(是一個常數)

使用Redis 緩存

  • 數據所有用戶可見,單行數據的QPS>1 ,就需要考慮 Redis 緩存了

本地緩存

  • 原因 Redis 有 20 萬 QPS,但是單 key 的 QPS 只有幾千;
  • 而本地內存的讀寫性能有千萬(map 讀寫)
  • 所以當單行數據的 QPS>5000(參考阿里云的熱 key 二級緩存標準 QPS) 就可以考慮使用本地緩存了

數據的分類

  • 熱數據: 考慮極端熱數據的情景(1w 的 QPS)
  • 冷數據: 0 QPS(沒人訪問)
  • 由冷數據突然變成熱數據: QPS 0 突變-> QPS 2000

我們的核心要求是:

  1. 熱數據不能失效,因為熱數據失效容易造成緩存擊穿的問題
  2. 冷數據不能長時間儲存在緩存(redis)中: 控制成本
  3. 冷數據(沒有緩存)突變到熱數據(大量請求): 不能全部請求都回源(查詢 DB),否則會造成緩存擊穿問題

一致性的方案

1. 先清除Redis,再更新 DB
  • 存在的問題:
    • 間隙查詢的不一致問題
    • 有緩存擊穿的風險

舉個例子:

  1. 不一致
  • 再清除 Redis 后,更新 DB 前有一個查詢請求
  • 因為 DB 沒有更新,查詢請求查詢到舊數據,然后將舊數據更新到 Redis
  • 這時 Redis 中的就是一條臟數據,造成數據不一致的問題
  1. 如果清除到一條有 1萬 QPS 的 key 很容易發生擊穿的問題
2. 先更新DB,再清除 Redis
  • 存在的問題:
    • 緩存擊穿的問題

還是清除到 1 萬 QPS 的 key 很容易發生擊穿

使用場景:
  • QPS不高(單行數據QPS<20,不存在熱key 的場景)的非核心業務:比如用戶的主頁
3. 延遲刪除與延遲雙刪

工作流程: 先更新 DB,再等一段時間清除 Redis / 先清除 Redis,再更新 DB,再等一段時間清除 Redis

核心解決的問題: 查詢從庫導致的數據不一致的問題

舉個例子:

  • 更新 DB 是更新的主庫,從庫需要一段時間進行同步
  • 但是 DB更新完后,從庫沒有同步好,這時有一個查詢,查詢到有個未同步的從庫(舊數據)
  • 然后將數據更新到 Redis

所以延遲的作用就是等待從庫的數據同步好,保證數據一直

延遲多久?

  • 具體要根據項目中的同步的耗時單行數據的 qps來確定是否需要延遲刪除/延遲雙刪
使用場景
  • QPS不高(單行數據QPS<20,不存在熱key 的場景)的非核心業務:比如用戶的主頁 (本質與方案 2 是相同的,不能有熱 key; 只是增加了延遲解決從庫查詢的不一致問題)
4. 監聽 binlog 清除

解決的問題:

  • 將自當成 DB 的一個從節點,監聽主節點的 binlog,并刪除Redis
  • 服務解耦和: 與之前不同的是這種方案是低耦合實現

問題:

  • 同樣只適用于 QPS<20(沒有熱 key 問題的需求)
  • 實現復雜: 監聽 binlog 的邏輯是比較復雜的(比如 binlog 的獲取,解析,消費等)
5. 雙寫

工作流程: 先更新 DB,再更新 Redis

  • 存在的問題與解決方案
    • 并發寫的不一致問題
      • 舉個例子: 有兩個寫請求(請求 1,將數據改為 A; 請求 2 將數據改為 B)
      • 這時請求 1 先執行,將DB 改為 A,然后請求 1 阻塞
      • 請求 2 后執行,先將 DB 改成 B , 再將 Redis 改成 B
      • 這時請求 1 阻塞恢復了,將 Redis 改成 A
      • 這時 DB 是 B,Redis(緩存)是 A,造成了一個數據不一致的問題
    • 解決方案: 加分布式鎖,不允許同時更改,只能一個執行完成才能執行下一個
使用場景:
  • 完善一下

    • 熱數據的過期失效問題(自動續期)
    • 冷數據突變為熱數據(只放一個請求回源更新,其他請求返回空)
  • 完善后可以適用于高讀,高寫,高一致性的場景: 比如搶紅包業務

  • 搶紅包業務分析:

    • 紅包發出會有大量的搶紅包的操作,就涉及到大量的寫(并發寫)
    • 紅包發出有大量的人查詢搶紅包的記錄: 大量讀
    • 搶完紅包后需要所有人看到最新的記錄: 高的一致性
6. 監聽binlog更新

核心解決的問題

  • binlog 是有序的,如果能順序消費 binlog 就可以解決雙寫中并發寫的問題

如何訂閱 binlog?

  1. 使用Canal組件(原理就是偽裝成從節點向主節點發送 dump)

缺點:

  • 復雜,binlog 的獲取,解析,消費整套是比較復雜的邏輯(比鎖實現起來要更復雜),并且還要考慮過期失效的問題與冷數據突變為熱數據的問題
  • 一致性沒有雙寫好(雙寫使用了分布式鎖,基本就是一個強一致的方案)
7.定時刷新

實現方式:

  • 儲存(Redis)緩存的時候儲存一個數據的更新標記(val 是一個空值),并且 更新標記的過期時間<數據的過期時間

    • 比如:更新標記 10s 過期; 數據 10 分鐘過期
  • 查詢的時候先使用 set nx px 命令檢查更新標記是否存在,

    • 如果存在(寫失敗): 就使用 Redis 的數據
    • 如果不存在(寫成功): 就回源(查詢 DB)更新 Redis(更新數據與過期時間)

如此就可以實現數據的定時刷新(每個更新標記的存活時間刷新一次),這樣可以解決一致性的問題與熱數據過期失效的問題,一舉兩得

解決完熱數據的問題還剩冷數據與冷數據突變為熱數據

  1. 冷數據: 不使用會自動過期,釋放空間
  2. 冷數據突變為熱數據: 第一個會回源(set nx 成功),其他請求暫時返回空,知道回源完成

為什么是返回空而不是回源或者阻塞?

  1. 回源的問題: 擊穿
  2. 阻塞的問題: 阻塞大量的請求(協程)(假設有 1萬 QPS,回源需要 10s,就會阻塞 10 萬個請求)

優點:

  1. 實現簡單: 定時刷新同時解決了一致性問題與熱數據的失效問題
  2. 好拓展: 不僅適用于 Redis 與 DB 的一致性,還適用于內存與 Redis 的一致性
使用場景
  1. 一致性要求不高(不敏感): 比如要求是更新后 10 分鐘內可以看到數據最新的狀態
  2. 讀高: 有大量讀并存在熱點問題

比如: 短視頻平臺的視頻數據

選擇

  1. 封頂估算: 對單行數據進行封頂估算決定是否使用緩存,使用什么緩存
  2. 任務分解: 將實際需求中可能遇到的情況羅列出來(比如:熱數據,冷數據,冷數據突變為熱數據)
  3. 分析每一種情況,并提供對應的解決方案.

參考: https://blog.csdn.net/weixin_42338901/article/details/129231758

其他問題

上面主要解決的是擊穿問題,Redis 緩存的常見的三大問題還有兩個

  1. 緩存穿透: 使用不存在的 key 進行訪問
  2. 緩存雪崩: 緩存大面積失效
緩存穿透

常見的解決方案:

  1. 布隆過濾器
    實現: 多次哈希,然后標記對應的 bit 位(變為 1)
    判斷是否出現過: 多次哈希,所有 bit 位都為 1 才算

問題:

  • 不是 100% 準確的,存在誤判的可能
  • 只能記錄是否出現過(適合做加法,很難做減法)
    舉個例子: 某個 key 開始是不存在的,加到布隆過濾器中防止穿透,后面存在了;這時候別人訪問這個 key 就會攔截掉.
  1. 記錄空值
  • 相同的不存在的 key 重復訪問會攔截到 Redis 層

缺點:
比布隆過濾器消耗空間更大

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/71613.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/71613.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/71613.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用 Elasticsearch 進行集成測試初始化??數據時的注意事項

作者&#xff1a;來自 Elastic piotrprz 在創建應該使用 Elasticsearch 進行搜索、數據聚合或 BM25/vector/search 的軟件時&#xff0c;創建至少少量的集成測試至關重要。雖然 “模擬索引” 看起來很誘人&#xff0c;因為測試甚至可以在幾分之一秒內運行&#xff0c;但它們實際…

【selenium工具操作web頁面中的下拉框元素 】

使用F12定位下拉框中的元素 使用F12定位下拉框中的元素 1、有一類元素不是直接顯示的頁面上的&#xff0c;而是需要點擊某些其他元素后才會顯示在頁面上&#xff0c;比如這里的下拉框。 2、這類元素會有一個特點&#xff1a;鼠標如果移開(沒在元素上)&#xff0c;這些元素就會…

C++ set map 詳解

文章目錄 1. 容器2. set和multiset2.1 set2.1.1 構造函數2.1.2 insert和erase2.1.2.1 insert2.1.2.2 erase 2.1.3 查找和訪問2.1.3.1 set迭代器相關2.1.3.2 find && count2.1.3.3 范圍查找 2.2 multiset2.2.1 insert和erase2.2.2 find和count 2.3 set和multiset的在算法…

Unity網絡開發基礎 (2) 網絡協議基礎

本文章不作任何商業用途 僅作學習與交流 部分圖片來自Unity唐老師 目錄 1.虛擬模型 2.實際模型 TCP/IP 3.傳輸層協議 TCP/UDP TCP 協議詳解 1. 核心機制 2. 頭部格式&#xff08;20 字節最小&#xff09; UDP 協議詳解 1. 核心特點 2. 頭部格式&#xff08;固定 8 字節…

HTML label 標簽使用

點擊 <label> 標簽通常會使與之關聯的表單控件獲得焦點或被激活。 通過正確使用 <label> 標簽&#xff0c;可以使表單更加友好和易于使用&#xff0c;同時提高整體的可訪問性。 基本用法 <label> 標簽通過 for 屬性與 id 為 username 的 <input> 元素…

JDBC、MyBatis 、MyBatis-Plus面試總結(一)

以下為你整理了一些 MyBatis 和 MyBatis-Plus 中 mapper.xml 相關的常見面試問題及答案&#xff1a; 基礎概念類 問題 1&#xff1a;什么是 mapper.xml 文件&#xff0c;它在 MyBatis 中有什么作用&#xff1f; 答案&#xff1a;mapper.xml 文件是 MyBatis 中用于定義 SQL 語…

GCC RISCV 后端 -- GCC Passes 注釋

在前面文章提到&#xff0c;當GCC 前端完成對C源代碼解析完成后&#xff0c;就會使用 處理過程&#xff08;Passes&#xff09;機制&#xff0c;通過一系列的處理過程&#xff0c;將 GENERIC IR 表示的C程序 轉步轉換成 目標機器的匯編語言。過程描述如下圖所示&#xff1a; 此…

基于Python實現的智能旅游推薦系統(Django)

基于Python實現的智能旅游推薦系統(Django) 開發語言:Python 數據庫&#xff1a;MySQL所用到的知識&#xff1a;Django框架工具&#xff1a;pycharm、Navicat 系統功能實現 總體設計 系統實現 系統首頁模塊 統首頁頁面主要包括首頁&#xff0c;旅游資訊&#xff0c;景點信息…

鴻蒙全棧開發 D2

課程目標 掌握ArkTS基礎語法與核心概念理解聲明式UI開發范式能獨立開發簡單鴻蒙應用組件建立規范的代碼編寫習慣 第一部分&#xff1a;初識ArkTS 1.1 語言全景認知 #mermaid-svg-V5mnjQN3DAHkfoBo {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size…

【YashanDB認證】yashandb23.3.1 個人版單機部署安裝實踐

YCA報名鏈接如下: YashanDB|崖山數據庫系統YashanDB學習中心-YCA認證詳情 目前免費 主要參考文檔&#xff1a; 單機&#xff08;主備&#xff09;部署 | YashanDB Doc 另外還參考摩天輪文章&#xff1a; YashanDB 23.2.9.101 企業版安裝步驟搶先看&#xff01; - 墨天輪 …

【藍橋杯】每天一題,理解邏輯(3/90)【Leetcode 快樂數】

閑話系列&#xff1a;每日一題&#xff0c;禿頭有我&#xff0c;Hello&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;,我是IF‘Maxue&#xff0c;歡迎大佬們來參觀我寫的藍橋杯系列&#xff0c;我好久沒有更新博客了&#xff0c;因為up豬我寒假用自己的勞動換了…

爬蟲Incapsula reese84加密案例:Etihad航空

聲明: 該文章為學習使用,嚴禁用于商業用途和非法用途,違者后果自負,由此產生的一切后果均與作者無關 一、找出需要加密的參數 1.js運行 atob(‘aHR0cHM6Ly93d3cuZXRpaGFkLmNvbS96aC1jbi8=’) 拿到網址,F12打開調試工具,隨便搜索航班,切換到network搜索一個時間點可以找…

緩存雪崩 緩存擊穿 緩存穿透

1. redis使用場景-緩存-緩存穿透 在實際開發中&#xff0c;Redis 被廣泛應用于緩存&#xff0c;以提高系統性能和響應速度。然而&#xff0c;在使用緩存時&#xff0c;需要注意一些問題&#xff0c;其中 緩存穿透 是一個常見且需要重點關注的場景。 什么是緩存穿透 ● 緩存穿…

【YOLOv12改進trick】多尺度大核注意力機制MLKA模塊引入YOLOv12,實現多尺度目標檢測漲點,含創新點Python代碼,方便發論文

??改進模塊??:多尺度大核注意力機制(MLKA) ??解決問題??:MLKA模塊結合多尺度、門控機制和空間注意力,顯著增強卷積網絡的模型表示能力。 ??改進優勢??:超分辨的MLKA模塊對小目標和模糊目標漲點很明顯 ??適用場景??:小目標檢測、模糊目標檢測等 ??思路…

better-sqlite3之exec方法

在 better-sqlite3 中&#xff0c;.exec() 方法用于執行包含多個 SQL 語句的字符串。與預編譯語句相比&#xff0c;這種方法性能較差且安全性較低&#xff0c;但有時它是必要的&#xff0c;特別是當你需要從外部文件&#xff08;如 SQL 腳本&#xff09;中執行多個 SQL 語句時。…

電路基礎:【1】PN結二極管制作電橋點亮LED燈

第一章&#xff1a;PN結二極管制作電橋點亮LED燈 文章目錄 第一章&#xff1a;PN結二極管制作電橋點亮LED燈前言一、電路原理二、電路圖與元器件1.電路圖 做實驗總結 前言 在本章中&#xff0c;我們將探討如何通過PN結二極管制作電橋電路&#xff0c;并利用該電路點亮LED燈。L…

XHR請求解密:抓取動態生成數據的方法

在如今動態頁面大行其道的時代&#xff0c;傳統的靜態頁面爬蟲已無法滿足數據采集需求。尤其是在目標網站通過XHR&#xff08;XMLHttpRequest&#xff09;動態加載數據的情況下&#xff0c;如何精準解密XHR請求、捕獲動態生成的數據成為關鍵技術難題。本文將深入剖析XHR請求解密…

機器學習數學基礎:42.AMOS 結構方程模型(SEM)分析的系統流程

該流程圖完整呈現了 AMOS 結構方程模型&#xff08;SEM&#xff09;分析的系統流程&#xff0c;具體步驟及內涵如下&#xff1a; 1. 模型設定 基于理論基礎或研究假設&#xff0c;構建結構方程模型的初始框架&#xff0c;明確潛變量與顯變量的關系、測量模型&#xff08;因子…

以太網通訊

接口開發筆記-WebApi-CSDN博客 以太網常用通訊協議 1、modbus tcp using EasyModbus; using System;class Program {static void Main(string[] args){// 創建Modbus客戶端實例ModbusClient modbusClient new ModbusClient("192.168.1.100"); // IP地址modbusCli…

Arcgis中添加腳本工具箱

文章目錄 準備資料1、打開arcmap2、找到目錄窗口3、復制粘貼工具箱的路徑4、添加或者確認python腳本路徑準備資料 (1)工具箱 (2)python腳本 1、打開arcmap 2、找到目錄窗口 3、復制粘貼工具箱的路徑 4、添加或者確認python腳本路徑 腳本上右鍵屬性(注意:腳本內容和路徑…