Redis + 布隆過濾器解決緩存穿透問題

Redis + 布隆過濾器解決緩存穿透問題

1. Redis + 布隆過濾器解決緩存穿透問題

📌 什么是緩存穿透?

緩存穿透指的是查詢的數據既不在緩存,也不在數據庫,導致每次查詢都直接訪問數據庫,增加數據庫壓力。
例如:攻擊者故意請求不存在的 ID,導致大量無效查詢,沖垮數據庫。

解決方案

  • 普通緩存機制:數據庫查詢為空時,寫入一個短期過期的空值,但對高并發請求不夠高效。

  • 布隆過濾器方案

    (推薦):

    1. 布隆過濾器預存已有數據的 key
    2. 查詢前,先通過布隆過濾器判斷 key 是否可能存在:
      • 存在 → 查詢 Redis 緩存,未命中則查詢數據庫,再寫入緩存。
      • 不存在 → 直接返回,避免訪問數據庫,防止緩存穿透。

2. Java 代碼示例:Redis + 布隆過濾器

📌 依賴

使用 Redisson 庫來操作 Redis 的布隆過濾器,需要添加以下依賴(使用 MavenGradle)。

<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.21.1</version>
</dependency>

📌 代碼示例

🚀 1. 初始化 Redis 連接
import org.redisson.Redisson;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;public class RedisBloomFilter {private static RedissonClient redissonClient;private static RBloomFilter<String> bloomFilter;static {// 配置 Redis 連接Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379"); // 連接本地 RedisredissonClient = Redisson.create(config);// 初始化布隆過濾器bloomFilter = redissonClient.getBloomFilter("product_bloom_filter");bloomFilter.tryInit(1000000L, 0.01); // 預估 100w 個元素,誤判率 1%}/*** 向布隆過濾器添加數據*/public static void addToBloomFilter(String productId) {bloomFilter.add(productId);}/*** 判斷數據是否可能存在*/public static boolean mightContain(String productId) {return bloomFilter.contains(productId);}public static void main(String[] args) {// 模擬初始化布隆過濾器addToBloomFilter("1001");addToBloomFilter("1002");addToBloomFilter("1003");// 查詢數據System.out.println("1001 存在?" + mightContain("1001")); // trueSystem.out.println("2001 存在?" + mightContain("2001")); // false}
}

🚀 2. 結合 Redis 緩存 + MySQL 數據庫

import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import redis.clients.jedis.Jedis;public class BloomFilterCacheDemo {private static Jedis redisClient = new Jedis("127.0.0.1", 6379);private static RedissonClient redissonClient;private static RBloomFilter<String> bloomFilter;static {// 配置 Redisson 連接 RedisredissonClient = Redisson.create();bloomFilter = redissonClient.getBloomFilter("product_bloom_filter");bloomFilter.tryInit(1000000L, 0.01); // 100w 數據,誤判率 1%}/*** 模擬查詢數據庫*/public static String queryDatabase(String productId) {if ("1001".equals(productId)) {return "商品1001:iPhone 15";} else if ("1002".equals(productId)) {return "商品1002:MacBook Pro";}return null; // 模擬數據庫查詢不到}/*** 查詢商品詳情(使用布隆過濾器+Redis緩存)*/public static String getProductInfo(String productId) {// 1?? 先查詢布隆過濾器if (!bloomFilter.contains(productId)) {return "商品不存在"; // 直接返回,防止緩存穿透}// 2?? 查詢 Redis 緩存String cacheData = redisClient.get("product:" + productId);if (cacheData != null) {return "【緩存】" + cacheData;}// 3?? 查詢數據庫String dbData = queryDatabase(productId);if (dbData != null) {// 寫入 Redis,設置 10 分鐘過期redisClient.setex("product:" + productId, 600, dbData);return "【數據庫】" + dbData;}return "商品不存在";}public static void main(String[] args) {// 初始化布隆過濾器(模擬數據庫已有商品)bloomFilter.add("1001");bloomFilter.add("1002");// 測試查詢System.out.println(getProductInfo("1001")); // 【數據庫】商品1001:iPhone 15System.out.println(getProductInfo("2001")); // 商品不存在}
}

3. 運行結果

查詢商品 IDRedis 緩存數據庫布隆過濾器返回結果
1001? 無? 有? 可能存在【數據庫】商品1001:iPhone 15
1001(第二次查詢)? 有-? 可能存在【緩存】商品1001:iPhone 15
2001(不存在)? 無? 無? 一定不存在商品不存在

4. 關鍵點總結

? 布隆過濾器防止緩存穿透

  • 先用布隆過濾器檢查,如果 不在過濾器內,直接返回,避免查詢數據庫。

? Redis 作為緩存

  • 查詢時,優先訪問 Redis,如果緩存未命中,才訪問數據庫,并寫入 Redis 進行緩存。

? 誤判率低

  • 通過 bloomFilter.tryInit(1000000L, 0.01),設置合理的 n(數據量)和 p(誤判率),確保高效過濾。

? 不能刪除數據

  • 布隆過濾器不支持刪除,可以用定期重建的方式優化,例如每天重新初始化。

5. 適用場景

🔹 電商系統:防止查詢不存在的商品 ID,減少數據庫壓力。
🔹 用戶系統:防止查詢不存在的用戶 ID,避免賬號碰撞攻擊。
🔹 API 限流:判斷 IP 或 Token 是否在黑名單,快速拒絕非法請求。

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

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

相關文章

Vue動態添加或刪除DOM元素:購物車實例

Vue 指令系列文章: 《Vue插值:雙大括號標簽、v-text、v-html、v-bind 指令》 《Vue指令:v-cloak、v-once、v-pre 指令》 《Vue條件判斷:v-if、v-else、v-else-if、v-show 指令》 《Vue循環遍歷:v-for 指令》 《Vue事件處理:v-on 指令》 《Vue表單元素綁定:v-model 指令》…

vue h5實現車牌號輸入框

哈嘍&#xff0c;大家好&#xff0c;最近鵬仔開發的項目是學校校內車輛超速方面的統計檢測方面的系統&#xff0c;在開發過程中發現有個小功能&#xff0c;就是用戶移動端添加車牌號&#xff0c;剛開始想著就一個輸入框&#xff0c;提交時正則效驗一下格式就行&#xff0c;最后…

硬件基礎(5):(3)二極管的應用

文章目錄 [toc]1. **整流電路****功能**&#xff1a;**工作原理**&#xff1a;**應用實例**&#xff1a;電路組成&#xff1a;整流過程&#xff1a;電路的應用&#xff1a; 2. **穩壓電路****功能**&#xff1a;**工作原理**&#xff1a;**應用實例**&#xff1a;電路組成及功能…

Wireshark網絡抓包分析使用詳解

序言 之前學計網還有前幾天備考華為 ICT 網絡賽道時都有了解認識 Wireshark&#xff0c;但一直沒怎么專門去用過&#xff0c;也沒去系統學習過&#xff0c;就想趁著備考的網絡相關知識還沒忘光&#xff0c;先來系統學下整理點筆記~ 什么是抓包&#xff1f;抓包就是將網絡傳輸…

安心聯車輛管理平臺源碼價值分析

安心聯車輛管理平臺源碼的價值可從技術特性、功能覆蓋、市場適配性、擴展潛力及商業化支持等多個維度進行分析。以下結合實際應用進行詳細解讀&#xff1a; 一、技術架構與開發優勢 主流技術棧與高性能架構 源碼采用成熟的前后端分離架構&#xff0c;后端基于Java技術&#xff…

【操作系統】Docker如何使用-續

文章目錄 1、概述2、鞏固知識2.1、基礎命令2.2、容器管理2.3、鏡像管理2.4、網絡管理2.5、Compose 3、常用命令 1、概述 在使用Docker的過程中&#xff0c;掌握常用的命令是至關重要的。然而&#xff0c;隨著時間的推移&#xff0c;我們可能會遺忘一些關鍵的命令或對其用法變得…

ElementUI el-menu導航開啟vue-router模式

有沒有小伙伴遇到這么一種情況&#xff1a;ElementUI el-menu導航中&#xff0c;開啟vue-router 的模式后&#xff0c;點擊觸發事件而不進行路由跳轉&#xff1f; 別慌&#xff01;下面直接說解決方案&#xff1a; 借助路由守衛進行判斷 給el-menu綁定切換事件&#xff0c;給…

【leetcode hot 100 17】電話號碼的字母組合

分析&#xff1a;當設計關鍵字“所有組合”時&#xff0c;要考慮深度優先遍歷、廣度優先遍歷&#xff08;層次遍歷&#xff09;&#xff0c;其中&#xff1a; 深度優先搜索&#xff1a; 自頂向下的遞歸實現深搜定義子問題在當前遞歸層結合子問題結果解決原問題 廣度優先搜索 利…

Vue 2 探秘:visible 和 append-to-body 是誰的小秘密?

&#x1f680; Vue 2 探秘&#xff1a;visible 和 append-to-body 是誰的小秘密&#xff1f;&#x1f914; 父組件&#xff1a;identify-list.vue子組件&#xff1a;fake-clue-list.vue 嘿&#xff0c;各位前端探險家&#xff01;&#x1f44b; 今天我們要在 Vue 2 的代碼叢林…

C++學習之路:從頭搞懂配置VScode開發環境的邏輯與步驟

目錄 編輯器與IDE基于vscode的C開發環境配置1. 下載vscode、淺嘗編譯。番外篇 2. 安裝插件&#xff0c;賦能編程。3. 各種json文件的作用。c_cpp_properties.jsontask.jsonlaunch.json 總結&&彩蛋 編輯器與IDE 上一篇博客已經介紹過了C程序的一個編譯流程&#xff0c;從…

PPT 轉高精度圖片 API 接口

PPT 轉高精度圖片 API 接口 文件處理 / 圖片處理&#xff0c;將 PPT 文件轉換為圖片序列。 1. 產品功能 支持將 PPT 文件轉換為高質量圖片序列&#xff1b;支持 .ppt 和 .pptx 格式&#xff1b;保持原始 PPT 的布局和樣式&#xff1b;轉換后的圖片支持永久訪問&#xff1b;全…

VSCode 抽風之 兩個conda環境同時在被激活

出現了神奇的(toolsZCH)(base) 提示符&#xff0c;如下圖所示&#xff1a; 原因大概是&#xff1a;conda 環境的雙重激活&#xff1a;可能是 conda 環境沒有被正確清理或初始化&#xff0c;導致 base 和 toolsZCH 同時被激活。 解決辦法就是 &#xff1a;conda deactivate 兩次…

git | 回退版本 并保存當前修改到stash,在進行整合。[git checkout | git stash 等方法 ]

目錄 一些常見命令&#xff1a; git 回退版本 一、臨時回退&#xff08;不會修改歷史&#xff0c;可隨時回到當前版本&#xff09; 方法1&#xff1a;git checkout HEAD~1 問題&#xff1a;處于 detached HEAD 狀態下提交的&#xff0c;無法直接 git push ? 選項 1&…

如何使用 Postman 進行接口測試?

使用 Postman 這一工具&#xff0c;可以輕松地進行接口測試。以下是一份簡單的使用教程&#xff0c;幫助你快速上手。 Postman 接口測試教程&#xff1a;詳細步驟及操作技巧

寫作軟件新體驗:讓文字創作更高效

一、開篇引入:寫作難題的破解之道 在當今信息爆炸的時代,寫作成為了我們生活和工作中不可或缺的一部分。然而,面對繁瑣的寫作任務,我們時常感到力不從心,甚至陷入創作的瓶頸。那么,有沒有一款軟件能夠幫助我們破解這一難題,讓文字創作變得更加高效和輕松呢?答案是肯定…

大模型思維鏈COT:Chain-of-Thought Prompting Elicits Reasoningin Large Language Models

一、TL&#xff1b;DR 探索了COT&#xff08;chain-of-thought prompting&#xff09;通過一系列的中間推理步驟來顯著的提升了LLM的復雜推理能力在三個大型語言模型上的實驗表明&#xff0c;思維鏈提示能夠提升模型在一系列算術、常識和符號推理任務上的表現解釋了一下為什么…

systemd-networkd的配置文件的優先級 筆記250325

systemd-networkd的配置文件的優先級 systemd-networkd的配置文件優先級規則如下&#xff1a; 1. 目錄優先級 配置文件按以下目錄順序加載&#xff08;優先級從高到低&#xff09;&#xff1a; /etc/systemd/network&#xff08;用戶自定義配置&#xff0c;最高優先級&#x…

詳細說明windows系統函數::SetUnhandledExceptionFilter(ExceptionFilter)

::SetUnhandledExceptionFilter(ExceptionFilter); 是 Windows 編程中用于設置頂層未處理異常過濾器的關鍵 API 調用。它屬于 Windows 結構化異常處理&#xff08;SEH, Structured Exception Handling&#xff09;機制的一部分&#xff0c;主要用于捕獲那些未被程序內部處理的異…

決策樹算法詳解:從西瓜分類到實戰應用

目錄 0. 引言 1. 決策樹是什么&#xff1f; 1.1 生活中的決策樹 1.2 專業版決策樹 2. 如何構建決策樹&#xff1f; 2.1 關鍵問題&#xff1a;選哪個特征先判斷&#xff1f; 2.1.1 信息熵&#xff08;數據混亂度&#xff09; 2.1.2 信息增益&#xff08;劃分后的整潔度提…

超融合服務器是什么

超融合服務器的定義與背景 超融合服務器&#xff08;Hyperconverged Infrastructure, HCI&#xff09;是一種通過軟件定義技術&#xff0c;將計算、存儲、網絡和虛擬化功能整合到單一硬件平臺中的IT基礎設施解決方案。其核心目標是通過資源的高度集成和統一管理&#xff0c;簡…