redis緩存-更新策略-三大緩存問題

緩存:數據交換的緩沖區,存儲的數據的臨時地方,讀寫性能較高。

步驟:

  1. 先從redis里面查詢
    • 緩存命中:直接返回結果
    • 緩存未命中
  2. 從數據庫里面查詢
    • 沒有數據:返回null
    • 有數據:存到redis里面,并返回

緩存更新策略:

1、內存淘汰:redis內存不足時,自動淘汰一部分數據;

2、超時剔除:設置TTL過期時間;

3、主動更新:查詢數據庫時就更新redis。

按業務場景去使用:

低一致性:內存淘汰

高一致性:主動更新,超時剔除作為兜底

主動更新策略

  1. Cache Aside Pattern調用者自己編碼,更新數據庫時更新緩存
  2. Read/Write Through Pattern緩存和數據庫整合為一個服務,調用者使用該服務
  3. Write Behind Caching Pattern調用者僅僅操作緩存,由其他的線程異步將緩存數據持久化到數據庫

緩存穿透

緩存穿透的定義
緩存穿透是指客戶端請求的數據在緩存和數據庫中都不存在,這樣每次請求都會穿透緩存直接訪問數據庫。如果大量這樣的請求同時出現,可能會導致數據庫壓力過大,甚至造成數據庫服務崩潰。
例如,攻擊者故意使用一些不存在的用戶 ID 頻繁請求用戶信息接口,由于這些用戶 ID 對應的信息在緩存和數據庫中都沒有,就會使這些請求直接打到數據庫上。
緩存穿透產生的原因
惡意攻擊:攻擊者通過構造大量不存在的鍵來頻繁請求服務,試圖使數據庫過載。
業務邏輯問題:在業務代碼中,可能存在沒有對數據是否存在進行有效驗證就直接查詢數據庫的情況。比如,在一個電商系統中,商品 ID 如果沒有經過合法性檢查,可能會有一些無效的 ID 被當作正常請求發送到數據庫。

緩存穿透的解決方案

緩存空對象

原理:當從數據庫查詢數據發現不存在時,在緩存中緩存一個空對象(可以使用一個特定的標記值來表示空對象),并設置一個較短的過期時間。這樣,下次同樣的請求過來時,會在緩存中命中這個空對象,避免直接訪問數據庫。

優缺點:
優點:簡單有效,能夠快速解決大部分緩存穿透問題。
缺點:

  • 如果惡意攻擊者使用大量不同的不存在的鍵進行攻擊,緩存中會存儲大量的空對象,占用緩存空空間,可以將過期時間設置的短一點。
  • 會造成數據短期的不一致。id不存在,緩存了一個空值,當新的數據來時,并且和當前緩存空對象的id一致。會造成redis緩存是空,但是實際上有這條數據。當該id數據被訪問時,走redis取出的就會是空。可以給過期時間設置短一點,或者在插入數據時跟新一下緩存。

布隆過濾器(Bloom Filter)

原理:布隆過濾器是一種概率型數據結構,它可以用來判斷一個元素是否在一個集合中。它的原理是通過多個哈希函數對元素進行哈希運算,將結果對應的位在一個位數組中置為 1。當查詢一個元素是否存在時,對該元素進行同樣的哈希運算,如果所有對應的位都是 1,則該元素可能存在;如果有任何一位是 0,則該元素一定不存在。
示例:使用 Google Guava 庫中的布隆過濾器(這只是一個簡單示例,實際應用中可能需要根據數據量和誤判率等因素調整參數)。

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import java.nio.charset.Charset;
public class BloomFilterExample {public static void main(String[] args) {// 創建一個布隆過濾器,預計插入1000個元素,誤判率為0.01BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.forName("UTF - 8")), 1000, 0.01);// 假設這些是數據庫中存在的用戶IDString[] existingUserIds = {"1", "2", "3"};for (String userId : existingUserIds) {bloomFilter.put(userId);}// 檢查用戶ID是否可能存在String nonExistentUserId = "4";if (!bloomFilter.mightExist(nonExistentUserId)) {System.out.println("這個用戶ID大概率不存在,無需查詢數據庫");}}
}

優缺點:

優點:可以高效地過濾掉大量不存在的元素,節省緩存空間和數據庫查詢次數。

缺點:實現復雜,存在一定的誤判率,即有可能將實際上不存在的元素判斷為可能存在,但可以通過調整參數來降低誤判率。而且布隆過濾器本身也需要占用一定的內存空間。

主動避免緩存穿透

上面的都是被動去接受緩存穿透,但是可以主動去避免。

  1. 增強id的復雜性,避免被猜出id;
  2. 對傳來的id做基本的格式校驗,將不符合要求的id給pass掉;
  3. 做好熱點參數的限流(微服務)
  4. 加強用戶權限的校驗,用戶沒有權限不能訪問一些接口。

緩存雪崩

緩存雪崩是指在同一時段大量的緩存key同時失效或者Redis服務宕機,導致大量請求到達數據庫,帶來巨大壓力。

解決方案:

  • 給不同的Key的TTL添加隨機值
  • 利用Redis集群提高服務的可用性
  • 給緩存業務添加降級限流策略(微服務)
  • 給業務添加多級緩存(微服務)

緩存擊穿

緩存擊穿問題也叫熱點Key問題,就是一個被高并發訪問并且緩存重建業務較復雜的key突然失效了,無數的請求訪問會在瞬間給數據庫帶來巨大的沖擊。

緩存重建業務較復雜 :查詢數據庫建立緩存耗時較長(幾十、幾百毫秒),在這個時間內可能有多個其他的線程也來訪問,去查數據庫,照成數據庫壓力過大。

解決方案:

互斥鎖

多個線程來訪問,當一個線程訪問未命中時,獲取鎖,然后查數據庫,建立緩存,釋放鎖;在這個時間內,其他的線程再來時,獲取不到鎖,一直等待帶線程釋放鎖。

優點:保證一致性;

缺點

其他的許多線程會等待該線程執行完成,性能下降;

可能引發死鎖。

邏輯過期

適用于緩存熱點key,提前有緩存預熱。

把過期時間設置在 redis的value中,注意:這個過期時間并不會直接作用于redis,而是我們后續通過邏輯去處理。

假設線程1去查詢緩存,然后從value中判斷出來當前的數據已經過期了,此時線程1去獲得互斥鎖,那么其他線程會進行阻塞,獲得了鎖的線程他會開啟一個 線程2去進行 以前的重構數據的邏輯,直到新開的線程2完成這個邏輯后,才釋放鎖, 而線程1直接進行返回,假設現在線程3過來訪問,由于線程線程2持有著鎖,所以線程3無法獲得鎖,線程3也直接返回數據,只有等到新開的線程2把重建數據構建完后,其他線程才能走返回正確的數據。

這種方案巧妙在于,異步的構建緩存,缺點在于在構建完緩存之前,返回的都是臟數據

優點:其他的線程無需等待;

缺點:不能保證數據的一致性;

緩存預熱 :活動開始時,對于一些熱點key,提前加到redis中,設置邏輯過期時間,所以說緩存一般是一定會命中的,未命中說明不是熱點key,返回null;活動結束,再刪除。

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

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

相關文章

[TriCore] 01.QEMU 虛擬化 TriCore 架構中的寄存器 指令

目錄 1.寄存器宏 - FIELD() 2.寄存器操作 - FIELD_SETTER() & FIELD_GETTER() 3.指令輔助方法 - HELPER() 3.1.輔助宏 3.2.指令示例 3.3.函數調用 4.PSW 寄存器讀寫 - psw_read() & psw_write() 1.寄存器宏 - FIELD() FIELD() 宏定義寄存器 MASK // include/hw…

《軟件工程》第 4 章 - 需求獲取

在軟件工程中&#xff0c;需求獲取是挖掘用戶真實需求的關鍵步驟&#xff0c;它為后續的設計、開發和測試提供堅實基礎。本章將圍繞需求獲取的流程、方法及工具展開&#xff0c;結合實際案例與 Java 代碼&#xff0c;深入講解這一重要環節。 4.1 軟件需求的初始表示 4.1.1 用例…

react diff 算法

diff 算法作為 Virtual DOM 的加速器&#xff0c;其算法的改進優化是 React 整個界面渲染的基礎和性能的保障&#xff0c;同時也是 React 源碼中最神秘的&#xff0c;最不可思議的部分 diff 算法會幫助我們就算出 VirtualDOM 中真正變化的部分&#xff0c;并只針對該部分進行原…

Gin項目腳手架與標配組件

文章目錄 前言設計思想和原則? 技術棧視頻實況教程sponge 內置了豐富的組件(按需使用)幾個標配常用組件主要技術點另一個參考鏈接 前言 軟件和汽車一樣&#xff0c;由多個重要零部件組裝而成。 本文堆積了一些常用部件&#xff0c;還沒來得及好好整理。先放著。 神兵利器雖多…

【Webtrees 手冊】第 10章 - 用戶體驗

Webtrees 手冊/用戶體驗 < Webtrees 手冊 跳轉到導航跳轉到搜索 信息 手冊部分仍在建設中 請耐心等待或隨意貢獻自己的力量:-)。 第 10 章 - 用戶體驗 <- 章節概述 目錄 1多位系譜學家的合作 1.1家庭研究模型1.2“孤膽戰士”模型1.3示范“本地家庭書”1.4模特“俱樂部”…

Linux 進程概念(下)

目錄 前言 4.進程狀態 一.普遍的操作系統層面上宏觀概念&#xff1a; 二.具體的Linux操作系統的狀態&#xff1a; 5.進程優先級&#xff08;了解&#xff09; 6.其他概念 進程切換 前言 本篇是接著上一篇的內容繼續往下了解進程相關的一些概念&#xff01; 4.進程狀態 運…

使用java實現word轉pdf,html以及rtf轉word,pdf,html

word,rtf的轉換有以下方案&#xff0c;想要免費最靠譜的是LibreOffice方案, LibreOffice 是一款 免費、開源、跨平臺 的辦公軟件套件&#xff0c;旨在為用戶提供高效、全面的辦公工具&#xff0c;適用于個人、企業和教育機構。它支持多種操作系統&#xff08;Windows、macOS、…

IP證書的作用與申請全解析:從安全驗證到部署實踐

在網絡安全領域&#xff0c;IP證書&#xff08;IP SSL證書&#xff09;作為傳統域名SSL證書的補充方案&#xff0c;專為公網IP地址提供HTTPS加密與身份驗證服務。本文將從技術原理、應用場景、申請流程及部署要點四個維度&#xff0c;系統解析IP證書的核心價值與操作指南。 一…

GitLab 18.0 正式發布,15.0 將不再受技術支持,須升級【三】

GitLab 是一個全球知名的一體化 DevOps 平臺&#xff0c;很多人都通過私有化部署 GitLab 來進行源代碼托管。極狐GitLab 是 GitLab 在中國的發行版&#xff0c;專門為中國程序員服務。可以一鍵式部署極狐GitLab。 學習極狐GitLab 的相關資料&#xff1a; 極狐GitLab 官網極狐…

超簡單Translation翻譯模型部署

Helsinki-NLP/opus-mt-{en}-{zh}系列翻譯模型可以實現200多種語言翻譯&#xff0c;Helsinki-NLP/opus-mt-en-zh是其中英互譯模型。由于項目需要&#xff0c;在本地進行搭建&#xff0c;并記錄下搭建過程&#xff0c;方便后人。 1. 基本硬件環境 CPU&#xff1a;N年前的 Intel…

Go語言JSON 序列化與反序列化 -《Go語言實戰指南》

JSON&#xff08;JavaScript Object Notation&#xff09;是一種常見的數據交換格式。Go 標準庫提供了 encoding/json 包&#xff0c;用于方便地將結構體與 JSON 之間互轉。 一、序列化&#xff08;Marshal&#xff09; 將 Go 中的數據結構&#xff08;如結構體、map、slice 等…

免費PDF工具-PDF24V9.16.0【win7專用版】

【百度】https://pan.baidu.com/s/1H7kvHudG5JTfxHg-eu2grA?pwd8euh 提取碼: 8euh 【夸克】https://pan.quark.cn/s/92080b2e1f4c 【123】https://www.123912.com/s/0yvtTd-XAHjv https://creator.pdf24.org/listVersions.php

網絡 :序列和反序列化

網絡 &#xff1a;序列和反序列化 &#xff08;一&#xff09;序列和反序列 概念&#xff08;二&#xff09;實例1. 封裝socket 接口2. 制定協議&#xff08;用于實現序列和反序列化&#xff09;3. 計算(實現計算器功能)4. 服務器(將上面所有的類功能調用起來)5. 服務端6.客戶端…

LiveQing 視頻點播流媒體 RTMP 推流服務功能:搭建 RTMP 視頻流媒體服務詳細指南

LiveQing視頻點播流媒體RTMP推流服務功能&#xff1a;搭建RTMP視頻流媒體服務詳細指南 一、流媒體服務搭建二、推流工具準備三、創建鑒權直播間四、獲取推流地址五、配置OBS推流六、推流及播放七、獲取播放地址7.1 頁面查看視頻源地址7.2 接口查詢 八、相關問題解決8.1 大疆無人…

UE5 Niagara 如何讓四元數進行旋轉

Axis Angle中&#xff0c;X,Y,Z分別為旋轉的軸向&#xff0c;W為旋轉的角度&#xff0c;在這里旋轉角度不需要除以2&#xff0c;因為里面已經除了&#xff0c;再將計算好的四元數與要進行旋轉的四元數進行相乘&#xff0c;結果就是按照原來的角度繞著某一軸向旋轉了某一角度

【微服務】SpringBoot 對接飛書審批流程使用詳解

目錄 一、前言 二、前置準備 2.1 開通企業飛書賬戶 2.2 確保賬戶具備多維表操作權限 2.3 獲取飛書開放平臺文檔 2.4 創建應用 2.5 發布應用 2.6 應用添加操作權限 2.7 獲取SDK 三、審批流程對接過程 3.1 配置流程審批定義(流程審批模型) 3.2 自定義應用添加審批AP…

主鍵與唯一鍵詳解:概念、區別與面試要點

主鍵與唯一鍵詳解:概念、區別與面試要點 一、核心概念解析 1.1 主鍵(Primary Key) 主鍵是數據庫表中用于唯一標識每一行記錄的列或列組合,具有以下核心特性: 唯一性:主鍵值在整個表中必須唯一,不允許重復非空性:主鍵列不允許包含NULL值不可變性:主鍵值一旦確立,原則…

前端面試準備-1

1.NodeJS的優缺點 優點&#xff1a;   高并發&#xff08;最重要的優點&#xff09;   適合I/O密集型應用 缺點&#xff1a;   不適合CPU密集型應用&#xff1b;CPU密集型應用給Node帶來的挑戰主要是&#xff1a;由于JavaScript單線程的原因&#xff0c;如果有長時間運行的…

GO并發過高導致程序崩潰如何解決

#作者&#xff1a;曹付江 文章目錄 1.并發過高導致程序崩潰2. 如何解決2.1 利用 channel 的緩存區2.2 利用第三方庫 3 調整系統資源的上限3.1 ulimit3.2 虛擬內存(virtual memory) 1.并發過高導致程序崩潰 看一個非常簡單的例子&#xff1a; func main() {var wg sync.WaitG…

Linux -- gdb/cgdb的認識和使用

預備知識 程序的發布?式有兩種&#xff0c; debug 模式和 release 模式&#xff0c; Linux gcc/g 出來的?進制程 序&#xff0c;默認是 release 模式。 要使?gdb調試&#xff0c;必須在源代碼?成?進制程序的時候, 加上 -g 選項&#xff0c;如果沒有添加&#x…