【JAVA架構師成長之路】【Redis】第14集:Redis緩存穿透原理、規避、解決方案

30分鐘自學教程:Redis緩存穿透原理與解決方案

目標

  1. 理解緩存穿透的成因及危害。
  2. 掌握布隆過濾器、空值緩存等核心防御技術。
  3. 能夠通過代碼實現請求攔截與緩存保護。
  4. 學會限流降級、異步加載等應急方案。

教程內容

0~2分鐘:緩存穿透的定義與核心原因
  • 定義:惡意或異常請求頻繁訪問數據庫中不存在的數據,繞過緩存直接沖擊數據庫。
  • 典型場景
    • 攻擊者偽造大量非法ID(如負數、超長字符串)。
    • 業務未對查詢參數校驗,或未緩存空結果。
  • 危害
    • 數據庫壓力激增,甚至宕機。
    • 正常服務被惡意請求拖垮。

2~5分鐘:代碼模擬穿透場景(Java示例)
// 未做防護的查詢方法(模擬穿透問題)  
public Product getProduct(String id) {  String key = "product:" + id;  Product product = redisTemplate.opsForValue().get(key);  if (product == null) {  // 直接查詢數據庫(未緩存空值)  product = productService.loadFromDB(id);  if (product != null) {  redisTemplate.opsForValue().set(key, product, 1, TimeUnit.HOURS);  }  }  return product; // 惡意請求會反復查詢數據庫  
}  

驗證問題

  • 使用JMeter發送100次id=-1的請求,觀察數據庫查詢次數是否為100次(穿透發生)。

5~12分鐘:解決方案1——布隆過濾器(Bloom Filter)
  • 原理:基于位數組和哈希函數,快速判斷數據是否可能存在于數據庫,攔截非法請求。
  • 代碼實現(Redisson布隆過濾器)
// 初始化布隆過濾器并預熱合法數據  
public class BloomFilterInit {  private RBloomFilter<String> bloomFilter;  @PostConstruct  public void init() {  bloomFilter = redissonClient.getBloomFilter("product_bloom");  bloomFilter.tryInit(100000L, 0.01); // 容量10萬,誤判率1%  List<String> validIds = productService.getAllValidIds();  validIds.forEach(bloomFilter::add);  }  
}  // 查詢時攔截非法請求  
public Product getProductWithBloomFilter(String id) {  if (!bloomFilter.contains(id)) {  return null; // 直接攔截  }  // 正常查詢邏輯...  
}  
  • 注意事項
    • 誤判率需根據業務容忍度調整(如0.1%更嚴格,但占用更多內存)。
    • 需定期同步布隆過濾器與數據庫的合法數據(如定時任務)。

12~20分鐘:解決方案2——空值緩存(Cache Null)
  • 原理:即使數據庫不存在該數據,也緩存空值(如“NULL”),避免重復穿透。
  • 代碼實現
public Product getProductWithNullCache(String id) {  String key = "product:" + id;  Product product = redisTemplate.opsForValue().get(key);  if (product == null) {  product = productService.loadFromDB(id);  if (product == null) {  // 緩存空值,5分鐘過期  redisTemplate.opsForValue().set(key, "NULL", 5, TimeUnit.MINUTES);  return null;  }  redisTemplate.opsForValue().set(key, product, 1, TimeUnit.HOURS);  } else if ("NULL".equals(product)) {  return null; // 直接返回空結果  }  return product;  
}  
  • 優化點
    • 空值過期時間不宜過長(避免存儲大量無效Key)。
    • 可結合布隆過濾器,減少空值緩存的數量。

20~25分鐘:解決方案3——請求參數校驗
  • 原理:在業務層攔截非法參數(如非數字ID、越界值)。
  • 代碼實現(Spring Boot參數校驗)
public Product getProduct(@PathVariable String id) {  // 校驗ID格式(僅允許數字)  if (!id.matches("\\d+")) {  throw new IllegalArgumentException("非法ID格式");  }  // 校驗ID范圍(如大于0)  long numericId = Long.parseLong(id);  if (numericId <= 0) {  throw new IllegalArgumentException("ID必須為正數");  }  // 正常查詢邏輯...  
}  
  • 擴展
    • 使用Hibernate Validator實現注解式校驗(如@Min(1))。

25~28分鐘:應急處理方案
  1. 限流降級(Guava RateLimiter)
private RateLimiter rateLimiter = RateLimiter.create(100); // 每秒100個請求  public Product getProduct(String id) {  if (!rateLimiter.tryAcquire()) {  throw new RuntimeException("請求過于頻繁,請稍后重試");  }  // 正常查詢邏輯...  
}  
  1. 異步加載(CompletableFuture)
public Product getProductAsync(String id) {  String key = "product:" + id;  Product product = redisTemplate.opsForValue().get(key);  if (product == null) {  CompletableFuture.runAsync(() -> {  Product dbProduct = productService.loadFromDB(id);  if (dbProduct != null) {  redisTemplate.opsForValue().set(key, dbProduct, 1, TimeUnit.HOURS);  }  });  }  return product; // 可能返回空,但避免阻塞請求  
}  

28~30分鐘:總結與優化方向
  • 核心原則:攔截非法請求、緩存空值、業務兜底。
  • 高級優化
    • 結合Redis Module的RedisBloom擴展(生產級布隆過濾器)。
    • 動態調整限流閾值(如根據數據庫負載自動限流)。

練習與拓展

練習

  1. 實現一個布隆過濾器,攔截id<=0的非法請求。
  2. 修改空值緩存邏輯,動態設置隨機過期時間(如5~15分鐘)。

推薦拓展

  1. 學習RedisBloom模塊的安裝與使用。
  2. 研究分布式限流框架(如Sentinel)的實現原理。
  3. 探索緩存穿透與緩存擊穿的綜合防護方案。

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

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

相關文章

尚硅谷爬蟲note15

一、當當網 1. 保存數據 數據交給pipelines保存 items中的類名&#xff1a; DemoNddwItem class DemoNddwItem(scrapy.Item): 變量名 類名&#xff08;&#xff09; book DemoNddwItem(src src, name name, price price)導入&#xff1a; from 項目名.items import 類…

LVGL直接解碼png圖片的方法

通過把png文件解碼為.C文件&#xff0c;再放到工程中的供使用&#xff0c;這種方式隨時速度快&#xff08;應為已經解碼&#xff0c;代碼中只要直接加載圖片數據顯示出來即可&#xff09;&#xff0c;但是不夠靈活&#xff0c;適用于哪些簡單又不經常需要更換UI的場景下使用。如…

【計算機網絡】Socket

Socket 是網絡通信的核心技術之一&#xff0c;充當應用程序與網絡協議棧之間的接口。 1. Socket 定義 Socket&#xff08;套接字&#xff09;是操作系統提供的 網絡通信抽象層&#xff0c;允許應用程序通過標準接口&#xff08;如 TCP/IP 或 UDP&#xff09;進行數據傳輸。它…

Apache XTable:在數據湖倉一體中推進數據互作性

Apache XTable 通過以多種開放表格式提供對數據的訪問&#xff0c;在增強互作性方面邁出了一大步。移動數據很困難&#xff0c;在過去&#xff0c;這意味著在為數據湖倉一體選擇開放表格式時&#xff0c;您被鎖定在該選擇中。一個令人興奮的項目當在數據堆棧的這一層引入互作性…

anolis8.9-k8s1.32-node-二進制部署

一、系統 # cat /etc/anolis-release Anolis OS release 8.9 # uname -r 5.10.134-18.an8.x86_64 二、從master上拷貝dockers及cri-docker相關文件 # groupadd docker # mkdir /etc/docker# scp -P 4033 root192.168.7.201:/etc/systemd/system/containerd.service /etc/s…

《AJAX:前端異步交互的魔法指南》

什么是AJAX AJAX&#xff08;Asynchronous JavaScript and XML&#xff0c;異步 JavaScript 和 XML&#xff09; 是一種用于創建異步網頁應用的技術&#xff0c;允許網頁在不重新加載整個頁面的情況下&#xff0c;與服務器交換數據并局部更新頁面內容。盡管名稱中包含 XML&…

Python 性能優化:從入門到精通的實用指南

Langchain系列文章目錄 01-玩轉LangChain&#xff1a;從模型調用到Prompt模板與輸出解析的完整指南 02-玩轉 LangChain Memory 模塊&#xff1a;四種記憶類型詳解及應用場景全覆蓋 03-全面掌握 LangChain&#xff1a;從核心鏈條構建到動態任務分配的實戰指南 04-玩轉 LangChai…

利用 requestrepo 工具驗證 XML外部實體注入漏洞

1. 前言 在數字化浪潮席卷的當下&#xff0c;網絡安全的重要性愈發凸顯。應用程序在便捷生活與工作的同時&#xff0c;也可能暗藏安全風險。XXE&#xff08;XML外部實體&#xff09;漏洞作為其中的典型代表&#xff0c;攻擊者一旦利用它&#xff0c;便能竊取敏感信息、掌控服務…

FreeRTOS第17篇:FreeRTOS鏈表實現細節05_MiniListItem_t:FreeRTOS內存優化

文/指尖動聽知識庫-星愿 文章為付費內容,商業行為,禁止私自轉載及抄襲,違者必究!!! 文章專欄:深入FreeRTOS內核:從原理到實戰的嵌入式開發指南 1 為什么需要迷你列表項? 在嵌入式系統中,內存資源極其寶貴。FreeRTOS為滿足不同場景需求,設計了標準列表項(ListItem_…

Spring 無法解決循環依賴的 5 種場景

一、構造器注入引發的循環依賴 1. 問題復現 Component public class ServiceA {private final ServiceB serviceB;Autowiredpublic ServiceA(ServiceB serviceB) { // 構造器注入this.serviceB serviceB;} }Component public class ServiceB {private final ServiceA servic…

Core Vision Kit(基礎視覺服務)

文章目錄 一、Core Vision Kit簡介場景介紹約束與限制二、通用文字識別三、人臉檢測一、Core Vision Kit簡介 Core Vision Kit(基礎視覺服務)是機器視覺相關的基礎能力,例如通用文字識別(即OCR,Optical Character Recognition,也稱為光學字符識別)、人臉檢測、人臉比對…

第TR3周:Pytorch復現Transformer

&#x1f368; 本文為&#x1f517;365天深度學習訓練營中的學習記錄博客 &#x1f356; 原作者&#xff1a;K同學啊 Transformer通過自注意力機制&#xff0c;改變了序列建模的方式&#xff0c;成為AI領域的基礎架構 編碼器&#xff1a;理解輸入&#xff0c;提取上下文特征…

FreeRTOS 任務間通信機制:隊列、信號量、事件標志組詳解與實驗

1. FreeRTOS 消息隊列 1.1 簡介 ? 隊列是 任務間通信的主要形式&#xff0c;可用于在任務之間以及中斷與任務之間傳遞消息。隊列在 FreeRTOS 中具有以下關鍵特點&#xff1a; 隊列默認采用 先進先出 FIFO 方式&#xff0c;也可以使用 xQueueSendToFront()實現 LIFO。FreeRT…

【虛擬化】Docker Desktop 架構簡介

在閱讀前您需要了解 docker 架構&#xff1a;Docker architecture WSL 技術&#xff1a;什么是 WSL 2 1.Hyper-V backend 我們知道&#xff0c;Docker Desktop 最開始的架構的后端是采用的 Hyper-V。 Docker daemon (dockerd) 運行在一個 Linux distro (LinuxKit build) 中&…

Unity光照之Halo組件

簡介 Halo 組件 是一種用于在游戲中創建光暈效果的工具&#xff0c;主要用于模擬光源周圍的發光區域&#xff08;如太陽、燈泡等&#xff09;或物體表面的光線反射擴散效果。 核心功能 1.光暈生成 Halo 組件會在光源或物體的周圍生成一個圓形光暈&#xff0c;模擬光線在空氣…

Flink深入淺出之01:應用場景、基本架構、部署模式

Flink 1?? 一 、知識要點 &#x1f4d6; 1. Flink簡介 Apache Flink — Stateful Computations over Data StreamsApache Flink 是一個分布式大數據處理引擎&#xff0c;可對有界數據流和無界數據流進行有狀態的計算。Flink 能在所有常見集群環境中運行&#xff0c;并能以…

2025年【高壓電工】報名考試及高壓電工考試總結

隨著電力行業的快速發展&#xff0c;高壓電工成為確保電力系統安全穩定運行的重要一環。為了提高高壓電工的專業技能和安全意識&#xff0c;“安全生產模擬考試一點通”平臺特別整理了2025年高壓電工報名考試的相關信息及考試總結&#xff0c;并提供了一套完整的題庫&#xff0…

網絡HTTP

HTTP Network Request Library A Retrofit-based HTTP network request encapsulation library that provides simple and easy-to-use API interfaces with complete network request functionality. 基于Retrofit的HTTP網絡請求封裝庫&#xff0c;提供簡單易用的API接口和完…

os-copilot安裝和使用體驗測評

簡介&#xff1a; OS Copilot是阿里云基于大模型構建的Linux系統智能助手&#xff0c;支持自然語言問答、命令執行和系統運維調優。本文介紹其產品優勢、功能及使用方法&#xff0c;并分享個人開發者在云服務器資源管理中的實際應用體驗。通過-t/-f/管道功能&#xff0c;OS Cop…

Python Flask框架學習匯編

1、入門級&#xff1a; 《Python Flask Web 框架入門》 這篇博文條理清晰&#xff0c;由簡入繁&#xff0c;案例豐富&#xff0c;分十五節詳細講解了Flask框架&#xff0c;強烈推薦&#xff01; 《python的簡單web框架flask【附例子】》 講解的特別清楚&#xff0c;每一步都…