Reids緩存穿透、緩存雪崩和緩存擊穿

Redis緩存中常見的三個問題:緩存穿透緩存雪崩緩存擊穿。這些問題在使用Redis作為緩存時經常遇到,但通過合理的策略可以有效解決。我會用簡單易懂的方式來講解,幫助你理解這些問題的原理和解決方案。


1. 緩存穿透

1.1 什么是緩存穿透?

緩存穿透是指查詢一個數據庫中不存在的數據,由于緩存不會保存這樣的數據,每次查詢都會直接穿透到數據庫,從而增加數據庫的壓力。

1.2 為什么會出現緩存穿透?

  • 請求非法數據:用戶請求了一個不存在的數據。

  • 緩存未命中:緩存中沒有保存這樣的數據,每次查詢都會直接訪問數據庫。

1.3 如何解決緩存穿透?

  1. 接口層面校驗

    • 在接口層面驗證請求的合法性,避免非法請求直接穿透到數據庫。

    • 例如,檢查請求的ID是否合法,是否符合業務邏輯。

  2. 緩存空對象

    • 對于查詢不存在的數據,將空對象或默認值緩存一段時間,避免每次查詢都穿透到數據庫。

    • 例如,緩存一個空的JSON對象或null值。

  3. 布隆過濾器

    • 使用布隆過濾器(Bloom Filter)預先存儲可能存在的數據ID,查詢時先檢查布隆過濾器。

    • 如果布隆過濾器判斷數據不存在,則直接返回,避免查詢數據庫。

示例代碼

const cache = require('some-cache-library'); // 假設的緩存庫
const database = require('some-database-library'); // 假設的數據庫庫async function getData(id) {// 檢查緩存let data = cache.get(id);if (data) {return data;}// 查詢數據庫data = await database.query(id);if (data) {// 緩存數據cache.set(id, data, 3600); // 緩存1小時} else {// 緩存空對象cache.set(id, null, 60); // 緩存1分鐘}return data;
}

2. 緩存雪崩

2.1 什么是緩存雪崩?

緩存雪崩是指在緩存層(如Redis)中的所有緩存數據同時過期,導致大量請求直接穿透到數據庫,從而引發數據庫壓力劇增甚至崩潰。

2.2 為什么會出現緩存雪崩?

  • 緩存過期時間一致:所有緩存數據的過期時間相同,導致同時過期。

  • 緩存層宕機:緩存層(如Redis)宕機,所有請求直接穿透到數據庫。

2.3 如何解決緩存雪崩?

  1. 設置不同的過期時間

    • 為緩存數據設置不同的過期時間,避免同時過期。

    • 例如,使用隨機的過期時間范圍。

  2. 使用本地緩存

    • 在應用層使用本地緩存(如Guava Cache),作為第一級緩存,減輕Redis的壓力。

  3. 使用Redis集群

    • 使用Redis集群,避免單點故障。

  4. 預熱緩存

    • 在系統啟動時,預先加載熱點數據到緩存中。

  5. 限流和降級

    • 在接口層面使用限流和降級策略,避免過多請求同時訪問數據庫。

示例代碼

const cache = require('some-cache-library'); // 假設的緩存庫
const database = require('some-database-library'); // 假設的數據庫庫async function getData(id) {// 檢查緩存let data = cache.get(id);if (data) {return data;}// 查詢數據庫data = await database.query(id);if (data) {// 緩存數據,設置隨機過期時間const randomExpire = 3600 + Math.floor(Math.random() * 3600); // 1-2小時cache.set(id, data, randomExpire);}return data;
}

3. 緩存擊穿

3.1 什么是緩存擊穿?

緩存擊穿是指一個熱點數據在緩存過期時,大量請求同時訪問數據庫,導致數據庫壓力劇增。

3.2 為什么會出現緩存擊穿?

  • 熱點數據過期:熱點數據的緩存過期,導致大量請求同時訪問數據庫。

  • 高并發請求:在緩存過期時,大量并發請求同時到達。

3.3 如何解決緩存擊穿?

  1. 使用互斥鎖

    • 在緩存過期時,使用互斥鎖(如Redis的SETNX命令)確保只有一個請求去查詢數據庫,其他請求等待。

    • 例如,使用SETNX命令設置一個鎖,只有第一個請求能夠查詢數據庫并更新緩存。

  2. 雙層緩存

    • 使用兩層緩存,第一層緩存(如本地緩存)過期時間稍短,第二層緩存(如Redis)過期時間稍長。

    • 第一層緩存過期時,第二層緩存仍然可用,避免直接穿透到數據庫。

  3. 預熱緩存

    • 在系統啟動時,預先加載熱點數據到緩存中,避免緩存過期時的高并發請求。

示例代碼

const cache = require('some-cache-library'); // 假設的緩存庫
const database = require('some-database-library'); // 假設的數據庫庫async function getData(id) {// 檢查緩存let data = cache.get(id);if (data) {return data;}// 設置互斥鎖const lockKey = `lock:${id}`;if (cache.set(lockKey, 'locked', 10)) { // 設置鎖,過期時間10秒try {// 查詢數據庫data = await database.query(id);if (data) {// 更新緩存cache.set(id, data, 3600);}} finally {// 釋放鎖cache.del(lockKey);}} else {// 等待其他請求更新緩存await new Promise(resolve => setTimeout(resolve, 1000));data = cache.get(id);}return data;
}

4. 總結

  • 緩存穿透:查詢不存在的數據,導致每次查詢都穿透到數據庫。

    • 解決方案:接口層面校驗、緩存空對象、使用布隆過濾器。

  • 緩存雪崩:所有緩存數據同時過期,導致大量請求穿透到數據庫。

    • 解決方案:設置不同的過期時間、使用本地緩存、使用Redis集群、預熱緩存、限流和降級。

  • 緩存擊穿:熱點數據過期時,大量請求同時訪問數據庫。

    • 解決方案:使用互斥鎖、雙層緩存、預熱緩存。

通過合理的策略和配置,可以有效解決Redis緩存中的這些問題,提高系統的穩定性和性能。

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

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

相關文章

附錄-Python — 包下載緩慢,配置下載鏡像

1??命令行配置 pip config set global.index-url http://mirrors.aliyun.com/pypi/simple/ pip config set install.trusted-host mirrors.aliyun.com 2??配置文件配置 1、打開文件夾,輸入 %APPDATA% 回車 2、打開 %APPDATA% 路徑,并在此路徑下新建…

VS 2019 免費版 下載與安裝 教程說明

推薦大家直接轉到第13步,點擊鏈接即可下載VS2019版本 1.VS官網 2.登錄賬號 3.在搜索欄輸入“2019” 4.點擊2019這個標題 5.點擊“下載” 6.選擇合適的版本下載 7.打開下載文件(若下載過程總是轉圈圈,則換個網絡下載即可) 8.安…

介紹 torch-mlir 從 pytorch 生態到 mlir 生態

一、引言 The Torch-MLIR project provides core infrastructure for bridging the PyTorch ecosystem and the MLIR ecosystem. For example, Torch-MLIR enables PyTorch models to be lowered to a few different MLIR dialects. Torch-MLIR does not attempt to provide a…

Java并發編程之ConcurrentHashMap的原理和使用

ConcurrentHashMap(CHM)是Java為解決高并發場景下哈希表性能瓶頸而設計的線程安全容器,其核心目標在于: 線程安全?:避免多線程操作導致的數據不一致問題?;高吞吐量?:通過細粒度鎖和無鎖化設計降低線程競爭?;動態擴展?:支持自動擴容與數據結構優化(如鏈表轉紅黑樹…

AbMole揭秘傷口愈合:IGF-1-SP1-CD248信號通路的新發現

科學家們揭示了一條新的信號通路——IGF-1-SP1-CD248,這一發現為理解傷口愈合障礙提供了新的視角,并為未來的研究開辟了新方向。 研究背景 糖尿病患者的傷口愈合是一個長期存在的挑戰。據統計,約15%的糖尿病患者會遭受慢性傷口的困擾&#…

Go入門之文件

以只讀方式打開文件 package mainimport ("fmt""io""os" )func main() {file, err : os.Open("./main.go")defer file.Close()if err ! nil {fmt.Println(err)return}fmt.Println(file)var tempSlice make([]byte, 128)var strSlice…

python量化交易——金融數據管理最佳實踐——使用qteasy管理本地數據源

文章目錄 統一定義的金融歷史數據表最重要的數據表數據表的定義交易日歷表的定義:交易日歷表: trade_calendar qteasy是一個功能全面且易用的量化交易策略框架, Github地址在這里。使用它,能輕松地獲取歷史數據,創建交易策略并完…

通過 PromptTemplate 生成干凈的 SQL 查詢語句并執行SQL查詢語句

問題描述 在使用 LangChain 和 Llama 模型生成 SQL 查詢時,遇到了 sqlite3.OperationalError 錯誤。錯誤信息如下: OperationalError: (sqlite3.OperationalError) near "sql SELECT Name FROM MediaType LIMIT 5; ": syntax error [SQL: …

STaR(Self-Taught Reasoner)方法:讓語言模型自學推理能力(代碼實現)

STaR(Self-Taught Reasoner)方法:讓語言模型自學推理能力 在大型語言模型(LLM)的推理能力優化中,STaR(Self-Taught Reasoner) 是一種引人注目的技術,屬于“修改提議分布…

Asp.Net Web API| React.js| EF框架 | SQLite|

asp.net web api EF SQLiteReact前端框架 設計一個首頁面,包含三個按鈕分別對應三類用戶(數據查看,設計人員,管理員),當點擊管理員的時候彈出一個前端頁面可以輸入信息(以學生數據為例&#…

[SWPUCTF 2022 新生賽]1z_unserialize

題目描述&#xff1a;是很簡單的反序列化噢 代碼審計看注釋 <?phpclass lyh{ //定義一個類為lyhpublic $url NSSCTF.com;//公共屬性&#xff0c;初始值為NSSCTF.compublic $lt; //公共屬性&#xff0c;沒有初始值public $lly; //公共屬性&…

【數據庫】Update兩階段提交

為什么要兩階段提交 事務提交之后&#xff0c;redo log和bin log 都是需要1持久化到磁盤中&#xff0c;但是這兩個是獨立的邏輯&#xff0c;可能出現半成功的狀態&#xff0c;這樣就造成兩份日志之間的邏輯不一致。如&#xff1a; 以id1&#xff0c;name ‘小明’執行 updat…

【藍橋】排序

1、sort簡介 sort函數包含在頭文件<algorithm>中sort函數使用之前&#xff0c;需要通過#include <algorithm>引入sort函數使用的是快速排列或類似快速排列的改進算法&#xff0c;時間復雜度一般為O(nlog(n)) 2、sort用法 2.1 基礎用法 #include <iostream>…

2024年中國城市統計年鑒(PDF+excel)

2024年中國城市統計年鑒&#xff08;PDFexcel&#xff09; 說明&#xff1a;包括地級縣級市 格式&#xff1a;PDFEXCEL 《中國城市統計年鑒》是一部全面反映中國城市發展狀況的官方統計出版物&#xff0c;包括各級城市的詳細統計數據。這部年鑒自1985年開始出版&#xff0c;…

android 資源selector寫法注意

1、res文件夾下面color文件夾,放的xml <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@color/color_brand1" android:s…

藍橋杯 燈籠大亂斗【算法賽】

問題描述 元宵佳節&#xff0c;一場別開生面的燈籠大賽熱鬧非凡。NN 位技藝精湛的燈籠師依次落座&#xff0c;每位師傅都有相應的資歷值&#xff0c;其中第 ii 位師傅的資歷值為 AiAi?。從左到右&#xff0c;師傅們的資歷值逐級遞增&#xff08;即 A1<A2<?<ANA1?&l…

商城源碼的框架

商城源碼的框架通常是基于某種Web開發框架或者電子商務平臺來構建的。以下是一些常見的商城源碼框架&#xff1a; WooCommerce&#xff1a;基于WordPress的電子商務插件&#xff0c;適用于小型到中型的在線商店。 Magento&#xff1a;一個功能強大和靈活的開源電子商務平臺&am…

HarmonyOS 5.0應用開發——多線程Worker和@Sendable的使用方法

【高心星出品】 文章目錄 多線程Worker和Sendable的使用方法開發步驟運行結果 多線程Worker和Sendable的使用方法 Worker在HarmonyOS中提供了一種多線程的實現方式&#xff0c;它允許開發者在后臺線程中執行長耗時任務&#xff0c;從而避免阻塞主線程并提高應用的響應性。 S…

避坑!用Docker搞定PHP開發環境搭建(Mac、Docker、Nginx、PHP-FPM、XDebug、PHPStorm、VSCode)

本次更新主要是對環境版本進行了更新&#xff0c;例如php 7.3.7升級到了7.3.8&#xff0c;另外之前的版本有同學踩了坑&#xff0c;主要是官方docker鏡像php:7.3.7-fpm和php:7.3.8-fpm使用了不同版本的debian&#xff0c;后面會提到&#xff0c;請各位同學留意。 因為最近換電腦…

自動化測試開發

4、Servlet模型&#xff08;一&#xff09; Servlet的編寫、訪問過程 Servlet簡介 Servlet是Java Servlet的簡稱&#xff0c;是小服務程序或服務連接器&#xff0c;是用Java編寫的服務器端程序&#xff0c;主要功能在于獲取請求&#xff0c;返回響應廣義&#xff1a;一個Ser…