Redis——緩存穿透、擊穿、雪崩

緩存穿透

什么是緩存穿透

緩存穿透說簡單點就是大量請求的 key 根本不存在于緩存中,導致請求直接到了數據庫上,根本沒有經過緩存這一層。舉個例子:某個黑客故意制造我們緩存中不存在的 key 發起大量請求,導致大量請求落到數據庫。

緩存穿透的大致流程

如下圖所示,用戶的請求最終都要跑到數據庫中查詢一遍。

?解決辦法

最基本的就是首先做好參數校驗,一些不合法的參數請求直接拋出異常信息返回給客戶端。比如查詢的數據庫 id 不能小于 0、傳入的郵箱格式不對的時候直接返回錯誤消息給客戶端等等。

1)緩存無效 key

如果緩存和數據庫都查不到某個 key 的數據就寫一個到 Redis 中去并設置過期時間,具體命令如下:?SET key value EX 10086?。這種方式可以解決請求的 key 變化不頻繁的情況,如果黑客惡意攻擊,每次構建不同的請求 key,會導致 Redis 中緩存大量無效的 key 。很明顯,這種方案并不能從根本上解決此問題。如果非要用這種方式來解決穿透問題的話,盡量將無效的 key 的過期時間設置短一點比如 1 分鐘。

另外,這里多說一嘴,一般情況下我們是這樣設計 key 的:?表名:列名:主鍵名:主鍵值?。

2)布隆過濾器

布隆過濾器是一個非常神奇的數據結構,通過它我們可以非常方便地判斷一個給定數據是否存在于海量數據中。我們需要的就是判斷 key 是否合法,有沒有感覺布隆過濾器就是我們想要找的那個“人”。

具體是這樣做的:把所有可能存在的請求的值都存放在布隆過濾器中,當用戶請求過來,先判斷用戶發來的請求的值是否存在于布隆過濾器中。不存在的話,直接返回請求參數錯誤信息給客戶端,存在的話才會走下面的流程。

加入布隆過濾器之后的緩存處理流程圖如下。

但是,需要注意的是布隆過濾器可能會存在誤判的情況。總結來說就是:?布隆過濾器說某個元素存在,小概率會誤判。布隆過濾器說某個元素不在,那么這個元素一定不在。

為什么會出現誤判的情況呢? 我們還要從布隆過濾器的原理來說!

我們先來看一下,當一個元素加入布隆過濾器中的時候,會進行哪些操作:

  1. 使用布隆過濾器中的哈希函數對元素值進行計算,得到哈希值(有幾個哈希函數得到幾個哈希值)。
  2. 根據得到的哈希值,在位數組中把對應下標的值置為 1。

我們再來看一下,當我們需要判斷一個元素是否存在于布隆過濾器的時候,會進行哪些操作:

  1. 對給定元素再次進行相同的哈希計算;
  2. 得到值之后判斷位數組中的每個元素是否都為 1,如果值都為 1,那么說明這個值在布隆過濾器中,如果存在一個值不為 1,說明該元素不在布隆過濾器中。

然后,一定會出現這樣一種情況:不同的字符串可能哈希出來的位置相同。?(可以適當增加位數組大小或者調整我們的哈希函數來降低概率)

緩存擊穿

什么是緩存擊穿

緩存擊穿是指在緩存系統中,某個被大量訪問的熱點數據在緩存中的有效期剛好到期,而此時大量并發請求同時過來訪問該數據,由于緩存中已無此數據,這些請求就會同時繞過緩存直接去訪問數據庫,從而導致數據庫瞬間承受巨大的查詢壓力,可能會影響數據庫甚至整個系統的正常運行。

解決方案

常見的解決方案有兩種:

互斥鎖

互斥鎖的解決思路就是在Redis進行緩存重建時,拿到一個互斥鎖,其他請求拿不到這個鎖就是乖乖等待鎖的釋放。

邏輯過期

邏輯過期的解決思路如下:

在存入redis的value中增加一個字段,該字段為過期時間加上x分鐘,通過計算就知道這個數據是否邏輯上過期,事實上沒過期一直存在redis中。

在redis進行緩存重建的時候,會另開一個線程進行重建并拿到互斥鎖,其他線程拿不到數據想要緩存重建時也拿不到鎖,那就直接返回舊數據。

互斥鎖方案:由于保證了互斥性,所以數據一致,且實現簡單,因為僅僅只需要加一把鎖而已,也沒其他的事情需要操心,所以沒有額外的內存消耗,缺點在于有鎖就有死鎖問題的發生,且只能串行執行性能肯定受到影響

邏輯過期方案: 線程讀取過程中不需要等待,性能好,有一個額外的線程持有鎖去進行重構數據,但是在重構數據完成前,其他的線程只能返回之前的數據,且實現起來麻煩

緩存雪崩

什么是緩存雪崩?

實際上,緩存雪崩描述的就是這樣一個簡單的場景:緩存在同一時間大面積的失效,后面的請求都直接落到了數據庫上,造成數據庫短時間內承受大量請求。?這就好比雪崩一樣,摧枯拉朽之勢,數據庫的壓力可想而知,可能直接就被這么多請求弄宕機了。

舉個例子:系統的緩存模塊出了問題比如宕機導致不可用。造成系統的所有訪問,都要走數據庫。

還有一種緩存雪崩的場景是:有一些被大量訪問數據(熱點緩存)在某一時刻大面積失效,導致對應的請求直接落到了數據庫上。?這樣的情況,有下面幾種解決辦法:

舉個例子 :秒殺開始 12 個小時之前,我們統一存放了一批商品到 Redis 中,設置的緩存過期時間也是 12 個小時,那么秒殺開始的時候,這些秒殺的商品的訪問直接就失效了。導致的情況就是,相應的請求直接就落到了數據庫上,就像雪崩一樣可怕。

解決辦法

(1)給不同的Key的TTL添加隨機值(推薦)
? ? ? ? 操作簡單,當我們在做緩存預熱的時候,就有可能在同一時間批量插入大量的數據,
那么如果它們的TTL都一樣的話就可能出現大量key同時過期的情況!!!
所以我們需要在設置過期時間TTL的時候,定義一個范圍,追加該范圍內的一個隨機數。
(2)利用Redis集群提高服務的可用性
? ? ? ? 使用集群提高可靠性
(3)給緩存業務添加降級限流策略
? ? ? ? 微服務的知識
(4)給業務添加多級緩存 ?
? ? ? ? 請求到達瀏覽器,nginx可以做緩存,未命中找Redis,再未命中找JVM,最后到數據庫......

?總結

我個人感覺redis的緩存穿透和緩存擊穿有部分是類似,而緩存擊穿和緩存雪崩又有一部分是類似的

緩存穿透和緩存擊穿的大至區別

  • 緩存擊穿指緩存中沒有但數據庫中有的數據(一般是緩存時間到期),這時由于并發用戶特別多,同時讀緩存沒讀到數據,又同時去數據庫去取數據,引起數據庫壓力瞬間增大,造成過大壓力。
  • 緩存穿透指查詢一個根本不存在的數據,緩存層和存儲層都不會命中,每次都會去請求數據庫,若有大量這樣的請求,可能會導致數據庫壓力過大甚至崩潰。

緩存擊穿和緩存雪崩的大至區別

  • 涉及數據范圍緩存擊穿主要針對的是單個熱點數據,是由于單個關鍵數據的緩存過期,大量請求同時訪問這一數據而引發問題;而緩存雪崩涉及的是大量數據,是大量緩存數據在同一時間或短時間內集體失效,導致大量請求沖向數據庫。
  • 引發原因側重:緩存擊穿更多是因為某個熱點數據的緩存時間設置不當,或者在緩存過期的瞬間有大量并發請求訪問;緩存雪崩除了可能因為緩存時間設置不合理外,還可能由于緩存服務器故障、大量數據同時更新等原因導致大量緩存數據同時失效
  • 問題表現形式緩存擊穿是大量請求集中訪問某一個特定數據緩存雪崩是大量請求分散地訪問多個不同的數據,但這些數據的緩存同時失效,導致整體請求流量對數據庫造成巨大沖擊。

文章參考

Redis的緩存穿透、緩存雪崩、緩存擊穿問題及有效解決方案_緩存雪崩和緩存穿透問題解決方案-CSDN博客

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

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

相關文章

DELETE/ UPDATE/ INSERT 語句會自動加鎖

在數據庫系統中,DELETE、UPDATE 和 INSERT 語句通常會自動加鎖,以確保數據的一致性和并發控制。具體的鎖類型和效果取決于數據庫的實現(如 MySQL、PostgreSQL 等)以及事務的隔離級別。以下是這些操作通常加鎖的行為和效果&#xf…

【從零開始學習計算機科學】硬件設計與FPGA原理

硬件設計 硬件設計流程 在設計硬件電路之前,首先要把大的框架和架構要搞清楚,這要求我們搞清楚要實現什么功能,然后找找有否能實現同樣或相似功能的參考電路板(要懂得盡量利用他人的成果,越是有經驗的工程師越會懂得借鑒他人的成果)。如果你找到了的參考設計,最好還是…

SpringCloud—概述—01

一、微服務 1)單體架構 業務的所有功能實現都打包在一個 war 包或者 jar 包中,這種方式就稱為 單體架構 例如,學校中實現的博客系統,前端后端數據庫實現,都是在一個項目中 把所有模塊都寫在一個 web 項目中&#x…

C++ 學生成績管理系統

一、項目背景與核心需求 成績管理系統是高校教學管理的重要工具,本系統采用C++面向對象編程實現,主要功能模塊包括: 學生信息管理(學號/姓名/3門課程成績) 成績增刪改查(CRUD)操作 數據持久化存儲 統計分析與報表生成 用戶友好交互界面 二、系統架構設計 1. 類結構設計 …

go的grpc

GRPC介紹 目錄 單體架構微服務架構問題原始的grpc 服務端客戶端原生rpc的問題 grpc的hello world 服務端客戶端 proto文件proto語法 數據類型 基本數據類型其他數據類型 編寫風格多服務 單體架構 只能對整體擴容一榮俱榮,一損俱損代碼耦合,項目的開…

1.12.信息系統的分類【ES】

專家系統(ES)技術架構深度解析 一、ES核心定義 🧠 智能決策中樞 由三大核心能力構建的領域專家模擬系統: 存儲專家級領域知識(10^4規則量級)支持不確定性推理(置信度>85%)動態…

考研數一非數競賽復習之Stolz定理求解數列極限

在非數類大學生數學競賽中,Stolz定理作為一種強大的工具,經常被用來解決和式數列極限的問題,也被譽為離散版的’洛必達’方法,它提供了一種簡潔而有效的方法,使得原本復雜繁瑣的極限計算過程變得直觀明了。本文&#x…

html播放本地音樂

本地有多個音樂文件,想用 html 逐個播放,或循環播放,并設置初始音量。 audio 在 html 中播放音樂文件用 audio 標簽: controls 啟用控制按鈕,如進度條、播放、音量、速度等。不加不顯示任何 widget。autoplay 理應啟…

DeepSeek-Manus精品課合集【附下載】

AI消息不斷,繼DeepSeek之后,又出了一個顛覆性的AI產品Manus,號稱全球第一個通用型AI。相比與DeepSeek, Manus擁有更強的自主性和執行力。 如果說DeepDeek是一個最強大腦,那么Manus就是一個完整的人! DeepS…

MySQL復習筆記

MySQL復習筆記 1.MySQL 1.1什么是數據庫 數據庫(DB, DataBase) 概念:數據倉庫,軟件,安裝在操作系統(window、linux、mac…)之上 作用:存儲數據,管理數據 1.2 數據庫分類 關系型數據庫&#…

從源到目標:深度學習中的遷移學習與領域自適應實踐

引言:數據驅動的智能時代與遷移挑戰 在深度學習快速發展的今天,模型訓練對數據量和質量的依賴成為核心瓶頸。面對新場景時,標注數據不足、數據分布差異等問題常導致模型性能驟降。遷移學習(Transfer Learning)與領域自…

【網絡】HTTP協議、HTTPS協議

HTTP與HTTPS HTTP協議概述 HTTP(超文本傳輸協議):工作在OSI頂層應用層,用于客戶端(瀏覽器)與服務器之間的通信,B/S模式 無狀態:每次請求獨立,服務器不保存客戶端狀態(通…

Jmeter使用介紹

文章目錄 前言Jmeter簡介安裝與配置JDK安裝與配置JMeter安裝與配置 打開JMeter方式一方式二 設置Jmeter語言為中文方法一(僅一次性)方法二(永久設置成中文) Jmeter文件常用目錄 元件與組件元件組件元件的作用域元件的執行順序第一個案例添加線程組添加 H…

【NLP 32、文本匹配任務 —— 深度學習】

大劫大難以后,人不該失去銳氣,不該失去熱度,你鎮定了卻依舊燃燒,你平靜了卻依舊浩蕩,致那個從絕望中走出來的自己,共勉 —— 25.1.31 使用深度學習在文本匹配任務上主要有兩種方式:① 表示型 ②…

發展史 | 深度學習 / 云計算

注:本文為來自 csdn 不錯的“深度學習 / 云計算發展史 ” 相關文章合輯。 對原文,略作重排。 深度學習發展史(1943-2024 編年體)(The History of Deep Learning) Hefin_H 已于 2024-05-23 15:54:45 修改 …

通領科技沖刺北交所

高質量增長奔赴產業新征程 日前,通領科技已正式啟動在北交所的 IPO 進程,期望借助資本市場的力量,加速技術升級,推動全球化戰略布局。這一舉措不僅展現了中國汽車零部件企業的強大實力,也預示著行業轉型升級的新突破。…

TCP/IP 5層協議簇:網絡層(ICMP協議)

1. TCP/IP 5層協議簇 如下: 和ip協議有關的才有ip頭 2. ICMP 協議 ICMP協議沒有端口號,因為不去上層,上層協議采用端口號

RISC-V匯編學習(三)—— RV指令集

有了前兩節對于RISC-V匯編、寄存器、匯編語法等的認識,本節開始介紹RISC-V指令集和偽指令。 前面說了RISC-V的模塊化特點,是以RV32I為作為ISA的核心模塊,其他都是要基于此為基礎,可以這樣認為:RISC-V ISA 基本整數指…

C語言 —— 愿此世如黃金般輝煌 - 進制轉換與操作符詳解

目錄 1. 操作符的分類 2. ?進制和進制轉換 2.1 2進制轉10進制 2.2 10進制轉2進制 2.3 2進制轉8進制 2.4 2進制轉16進制 3. 原碼、反碼、補碼 4. 移位操作符 4.1 左移操作符 4.2 右移操作符 5. 位操作符:&、|、^、~ 5.1 & 按位與 5.2 | 按位或 …

docker1

前言 技術架構 單機架構 應用數據分離架構 應用服務集群架構 讀寫分離/主從分離架構 寫入主的時候,要同步Mysql從的數據才可以 冷熱分離架構 寫的時候要寫入主和緩存數據庫 讀的時候先去緩存看有沒有,沒有的話就去從數據庫讀數據 主要就是看這個數據是…