Redis的緩存雪崩、緩存擊穿、緩存穿透與緩存預熱、緩存降級

一、緩存雪崩:

1、什么是緩存雪崩:

如果緩在某一個時刻出現大規模的key失效,那么就會導致大量的請求打在了數據庫上面,導致數據庫壓力巨大,如果在高并發的情況下,可能瞬間就會導致數據庫宕機。這時候如果運維馬上又重啟數據庫,馬上又會有新的流量把數據庫打死。這就是緩存雪崩。

2、問題分析:

造成緩存雪崩的關鍵在于同一時間的大規模的key失效,為什么會出現這個問題,主要有兩種可能:第一種是Redis宕機,第二種可能就是采用了相同的過期時間。搞清楚原因之后,那么有什么解決方案呢?

3、解決方案:

(1)事前:

① 均勻過期:設置不同的過期時間,讓緩存失效的時間盡量均勻,避免相同的過期時間導致緩存雪崩,造成大量數據庫的訪問。

② 分級緩存:第一級緩存失效的基礎上,訪問二級緩存,每一級緩存的失效時間都不同。

③ 熱點數據緩存永遠不過期。

永不過期實際包含兩層意思:

  • 物理不過期,針對熱點key不設置過期時間
  • 邏輯過期,把過期時間存在key對應的value里,如果發現要過期了,通過一個后臺的異步線程進行緩存的構建

④ 保證Redis緩存的高可用,防止Redis宕機導致緩存雪崩的問題。可以使用 主從+ 哨兵,Redis集群來避免 Redis 全盤崩潰的情況。

(2)事中:

① 互斥鎖:在緩存失效后,通過互斥鎖或者隊列來控制讀數據寫緩存的線程數量,比如某個key只允許一個線程查詢數據和寫緩存,其他線程等待。這種方式會阻塞其他的線程,此時系統的吞吐量會下降

② 使用熔斷機制,限流降級。當流量達到一定的閾值,直接返回“系統擁擠”之類的提示,防止過多的請求打在數據庫上將數據庫擊垮,至少能保證一部分用戶是可以正常使用,其他用戶多刷新幾次也能得到結果。

(3)事后:

① 開啟Redis持久化機制,盡快恢復緩存數據,一旦重啟,就能從磁盤上自動加載數據恢復內存中的數據。

二、緩存擊穿:

1、什么是緩存擊穿:

緩存擊穿跟緩存雪崩有點類似,緩存雪崩是大規模的key失效,而緩存擊穿是某個熱點的key失效,大并發集中對其進行請求,就會造成大量請求讀緩存沒讀到數據,從而導致高并發訪問數據庫,引起數據庫壓力劇增。這種現象就叫做緩存擊穿。

2、問題分析:

關鍵在于某個熱點的key失效了,導致大并發集中打在數據庫上。所以要從兩個方面解決,第一是否可以考慮熱點key不設置過期時間,第二是否可以考慮降低打在數據庫上的請求數量。

3、解決方案:

(1)在緩存失效后,通過互斥鎖或者隊列來控制讀數據寫緩存的線程數量,比如某個key只允許一個線程查詢數據和寫緩存,其他線程等待。這種方式會阻塞其他的線程,此時系統的吞吐量會下降

(2)熱點數據緩存永遠不過期。

永不過期實際包含兩層意思:

  • 物理不過期,針對熱點key不設置過期時間
  • 邏輯過期,把過期時間存在key對應的value里,如果發現要過期了,通過一個后臺的異步線程進行緩存的構建
三、緩存穿透:

1、什么是緩存穿透:

緩存穿透是指用戶請求的數據在緩存中不存在即沒有命中,同時在數據庫中也不存在,導致用戶每次請求該數據都要去數據庫中查詢一遍。如果有惡意攻擊者不斷請求系統中不存在的數據,會導致短時間大量請求落在數據庫上,造成數據庫壓力過大,甚至導致數據庫承受不住而宕機崩潰。

2、問題分析:

緩存穿透的關鍵在于在Redis中查不到key值,它和緩存擊穿的根本區別在于傳進來的key在Redis中是不存在的。假如有黑客傳進大量的不存在的key,那么大量的請求打在數據庫上是很致命的問題,所以在日常開發中要對參數做好校驗,一些非法的參數,不可能存在的key就直接返回錯誤提示。

3、解決方法:

(1)將無效的key存放進Redis中:

當出現Redis查不到數據,數據庫也查不到數據的情況,我們就把這個key保存到Redis中,設置value=”null”,并設置其過期時間極短,后面再出現查詢這個key的請求的時候,直接返回null,就不需要再查詢數據庫了。但這種處理方式是有問題的,假如傳進來的這個不存在的Key值每次都是隨機的,那存進Redis也沒有意義。

(2)使用布隆過濾器:

如果布隆過濾器判定某個 key 不存在布隆過濾器中,那么就一定不存在,如果判定某個 key 存在,那么很大可能是存在(存在一定的誤判率)。于是我們可以在緩存之前再加一個布隆過濾器,將數據庫中的所有key都存儲在布隆過濾器中,在查詢Redis前先去布隆過濾器查詢 key 是否存在,如果不存在就直接返回,不讓其訪問數據庫,從而避免了對底層存儲系統的查詢壓力。

如何選擇:針對一些惡意攻擊,攻擊帶過來的大量key是隨機,那么我們采用第一種方案就會緩存大量不存在key的數據。那么這種方案就不合適了,我們可以先對使用布隆過濾器方案進行過濾掉這些key。所以,針對這種key異常多、請求重復率比較低的數據,優先使用第二種方案直接過濾掉。而對于空數據的key有限的,重復率比較高的,則可優先采用第一種方式進行緩存。

四、緩存預熱:

1、什么是緩存預熱:

緩存預熱是指系統上線后,提前將相關的緩存數據加載到緩存系統。避免在用戶請求的時候,先查詢數據庫,然后再將數據緩存的問題,用戶直接查詢事先被預熱的緩存數據。

如果不進行預熱,那么Redis初始狀態數據為空,系統上線初期,對于高并發的流量,都會訪問到數據庫中, 對數據庫造成流量的壓力。

2、緩存預熱解決方案:

(1)數據量不大的時候,工程啟動的時候進行加載緩存動作;

(2)數據量大的時候,設置一個定時任務腳本,進行緩存的刷新;

(3)數據量太大的時候,優先保證熱點數據進行提前加載到緩存。

五、緩存降級:

緩存降級是指緩存失效或緩存服務器掛掉的情況下,不去訪問數據庫,直接返回默認數據或訪問服務的內存數據。降級一般是有損的操作,所以盡量減少降級對于業務的影響程度。

在項目實戰中通常會將部分熱點數據緩存到服務的內存中,這樣一旦緩存出現異常,可以直接使用服務的內存數據,從而避免數據庫遭受巨大壓力。

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

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

相關文章

Html5記憶翻牌游戲開發經驗分享

H5記憶翻牌游戲開發經驗分享 這里寫目錄標題 H5記憶翻牌游戲開發經驗分享前言項目概述技術要點解析1. 頁面布局(HTML CSS)響應式設計 2. 翻牌動畫效果3. 游戲邏輯實現狀態管理卡片配對檢測 開發技巧總結1. 模塊化設計2. 性能優化3. 用戶體驗 踩坑經驗擴…

【開源+代碼解讀】Search-R1:基于強化學習的檢索增強大語言模型框架3小時即可打造個人AI-search

大語言模型(LLMs)在處理復雜推理和實時信息檢索時面臨兩大挑戰:知識局限性(無法獲取最新外部知識)和檢索靈活性不足(傳統方法依賴固定檢索流程)。現有方法如檢索增強生成(RAG)和工具調用(Tool-Use)存在以下問題: RAG:單輪檢索導致上下文不足,無法適應多輪交互場景…

Linux網絡套接字編程——創建并綁定

目錄 網絡字節序 socket編程接口 socket bind 如果將進程比作一個房子,那套接字相當于是一扇門,通向與外界通信的通道。 在網絡中,如何理解套接字呢,時刻記住套接字是為了標識互聯網中的某一臺主機上的某一個進程&#xff0c…

1720. 解碼異或后的數組

解碼異或后的數組 題目描述嘗試做法 題目描述 未知整數數組 arr 由 n 個非負整數組成。 經編碼后變為長度為 n - 1 的另一個整數數組 encoded ,其中 encoded[i] arr[i] XOR arr[i 1] 。例如,arr [1,0,2,1] 經編碼后得到 encoded [1,2,3] 。 給你編…

了解一下HTTP的短連接和長連接

在 HTTP 協議中,連接的方式主要分為長連接和短連接。這兩種連接方式的主要區別在于連接的生命周期和數據傳輸的效率。理解它們的差異對于優化 Web 應用的性能和資源利用至關重要。以下是 HTTP 長連接和短連接的詳細解釋。 1. 短連接(HTTP/1.0&#xff0…

【WRF模擬】如何查看 WPS 的輸入靜態地理數據(二進制格式)?

查看 WPS 的輸入靜態地理數據方法總結 方法 1:使用 gdal_translate 將二進制數據轉換為 GeoTIFFgdal_translate 工具概述使用 gdal_translate 將二進制數據轉換為 GeoTIFF方法 2:使用 ncdump 查看 geo_em.dXX.nc方法 3:使用 Python xarray + matplotlib 可視化 geo_em.dXX.n…

Mybatis語法bug

select * from appointment where status ‘ACCEPTED’ and expire_time< now() idea顯示now&#xff08;&#xff09;這里一直報錯&#xff1a; 應為標記名稱 應為 Deepseek: 根據您的代碼和報錯信息分析&#xff0c;這是一個 MyBatis XML 文件中的 SQL 語法問題。具體原…

DeepSeek本機部署(基于Ollama和Docker管理)

目錄 一、ollama 與 docker 簡介 &#xff08;一&#xff09;ollama(Ollama) &#xff08;二&#xff09;docker 二、利用 ollama 和 docker 配置 deepseek-r1 的準備工作 &#xff08;一&#xff09;硬件需求 &#xff08;二&#xff09;軟件安裝 三、配置 deepseek-r1…

小程序 wxml 語法 —— 39 簡單雙向數據綁定

在 WXML 中&#xff0c;普通屬性的綁定是單向的&#xff0c;比如 <input value"{{ value }}" />&#xff0c;當數據發生改變時&#xff0c;頁面也會隨之發生變化&#xff0c;但是當用戶在輸入框中輸入最新內容&#xff0c;最新內容并不會同步給 value 數據&…

Linux第一次練習

1、找到你的Linux系統上的不同顏色的文件&#xff0c;每一種顏色的文件找到3個以上 藍色&#xff1a; 白色&#xff1a; 綠色&#xff1a; 紅色&#xff1a; 黃色&#xff1a; 2、設置一個ping的別名永久生效&#xff0c;設置一個ymd的別名date %F永久生效

《C#上位機開發從門外到門內》2-2:I2C總線協議及其應用詳解

文章目錄 一、引言二、I2C總線協議的基本概念三、I2C通信機制3.1 硬件結構與基本原理3.2 信號的起始與終止3.3 數據傳輸格式及時序3.4 時鐘同步與時鐘伸展 四、設備尋址與數據傳輸4.1 I2C設備尋址方式4.2 地址沖突及解決方法4.3 數據傳輸過程中的確認機制4.4 I2C數據幀結構與傳…

Trae IDE:解鎖 AI 驅動的高效編程體驗

Trae 介紹 Trae 是字節跳動推出的一款面向開發者的 AI 驅動的集成開發環境&#xff08;IDE&#xff09;&#xff0c;于 2024 年 1 月 19 日在新加坡正式發布海外版&#xff0c;2025 年 3 月 3 日發布國內版。海外版由字節跳動旗下的 SPRING&#xff08;SG&#xff09;PTE.LTD.…

玩轉python:通俗易懂掌握高級數據結構:collections模塊之namedtuple

引言 namedtuple是Python中collections模塊提供的一個強大工具&#xff0c;用于創建具有字段名的元組。它不僅具備元組的不可變性&#xff0c;還能通過字段名訪問元素&#xff0c;極大地提高了代碼的可讀性和可維護性。本文將詳細介紹namedtuple的關鍵用法和特性&#xff0c;并…

我的創作紀念日:730天的技術寫作之旅

我的創作紀念日&#xff1a;730天的技術寫作之旅 機緣 從一篇案例分析開始 2023年3月13日&#xff0c;我寫下了第一篇技術博客《軟考高級-系統分析師-案例分析-系統維護與設計模式》。那時的初心很簡單&#xff1a; 沉淀實戰經驗——在備考軟考系統分析師時&#xff0c;發現…

使用 Arduino 和 ESP8266 Wi-Fi 模塊發送電子郵件

使用 Arduino Uno 和 ESP8266 Wi-Fi 模塊發送電子郵件 我們正在邁向物聯網 (IoT) 世界。這項技術在電子和嵌入式系統中起著非常重要的作用。從任何微控制器或嵌入式系統發送電子郵件都是非常基本的事情,這在 IoT 中是必需的。因此,在本文中,我們將學習“如何使用 Wi-Fi 和…

golang算法二叉樹對稱平衡右視圖

100. 相同的樹 給你兩棵二叉樹的根節點 p 和 q &#xff0c;編寫一個函數來檢驗這兩棵樹是否相同。 如果兩個樹在結構上相同&#xff0c;并且節點具有相同的值&#xff0c;則認為它們是相同的。 示例 1&#xff1a; 輸入&#xff1a;p [1,2,3], q [1,2,3] 輸出&#xff1a…

c++介紹智能指針 十二(1)

普通指針&#xff1a;指向內存區域的地址變量。使用普通指針容易出現一些程序錯誤。 如果一個指針所指向的內存區域是動態分配的&#xff0c;那么這個指針變量離開了所在的作用域&#xff0c;這塊內存也不會自動銷毀。動態內存不進行釋放就會導致內存泄露。如果一個指針指向已…

亞馬遜COSMO算法解讀:新搜索時代的流量分配與DeepBI AI驅動的智能優化策略

亞馬遜COSMO算法的推出&#xff0c;標志著其搜索和推薦系統進入了智能化、個性化的新階段。該算法通過分析用戶購物習慣、搜索歷史、瀏覽行為等數據&#xff0c;為買家提供精準推薦&#xff0c;同時對賣家的運營策略提出了更高的要求。在這一背景下&#xff0c;AI驅動的DeepBI能…

C++編譯問題——1模板函數的實現必須在頭文件中

今天編譯數據結構時&#xff0c;遇見一個編譯錯誤 假設你有一個頭文件 SeqList.h 和一個源文件 SeqList.cpp。 SeqList.h #ifndef SEQLIST_H #define SEQLIST_H#include <stdexcept> #include <iostream>template<typename T> class SeqList { private:sta…

安卓實現魔改版 CRC32 算法

版權歸作者所有&#xff0c;如有轉發&#xff0c;請注明文章出處&#xff1a;https://cyrus-studio.github.io/blog/ 關于 CRC32 算法介紹可以參考這篇文章&#xff1a;常用加解密算法介紹 標準 CRC32 算法 創建 crc32.cpp&#xff0c;使用 C 實現標準 CRC32 算法 #include …