1.什么是緩存穿透
緩存穿透是指查詢一個數據庫中根本不存在的數據,導致這個查詢請求繞過緩存直接訪問數據庫的情況。這種情況如果頻繁發生,會對數據庫造成不必要的壓力。
典型特征:
(1)查詢的數據在數據庫和緩存中都不存在
(2)惡意攻擊者可能故意查詢大量不存在的數據來攻擊系統
解決方案?:
1. 緩存空對象
//優點:實現簡單
//缺點:可能緩存大量無用的空鍵,占用內存
// 偽代碼示例
public Object getData(String key) {Object value = cache.get(key);if (value != null) {if (value instanceof NullValue) { // 特殊標記的空對象return null;}return value;}value = db.get(key);if (value == null) {// 數據庫不存在,緩存一個特殊空對象,設置較短過期時間cache.set(key, new NullValue(), 60); // 60秒過期} else {cache.set(key, value);}return value;
}
2.布隆過濾器
//優點:內存效率高
//缺點:有一定誤判率(但不會漏判),需要維護布隆過濾器
// 偽代碼示例
public Object getData(String key) {if (!bloomFilter.mightContain(key)) {return null; // 肯定不存在}Object value = cache.get(key);if (value != null) {return value;}value = db.get(key);if (value != null) {cache.set(key, value);}return value;
}
2.什么是布隆過濾器
? ? ? 布隆過濾器是一種空間效率極高的概率型數據結構,用于快速判斷一個元素是否可能存在于集合中。它使用位數組和多個哈希函數實現,特點是查詢速度快、占用內存小,但有一定誤判率(可能誤報存在,但絕不會漏報)。典型應用包括緩存穿透防護、爬蟲URL去重等場景。
工作原理:
-
添加元素時,用k個哈希函數計算元素的哈希值,將位數組中對應位置設為1
-
查詢元素時,同樣計算k個哈希值,若所有對應位都為1則認為可能存在,任一為0則肯定不存在"
實際應用:
-
緩存系統:防止緩存穿透,如Redis緩存前先查布隆過濾器
-
網頁爬蟲:URL去重,避免重復爬取
-
安全領域:惡意網站/垃圾郵件過濾
-
數據庫優化:減少不必要的磁盤查詢"
優點:
-
內存占用極小(1億元素約需114MB,誤判率1%)
-
查詢性能與數據量無關
-
可并行化處理
缺點:
-
不能刪除元素(除非使用Counting Bloom Filter變種)
-
誤判率隨元素增加而升高
-
不支持獲取實際存儲的元素
"布隆過濾器的性能取決于三個參數:
-
位數組大小m:越大誤判率越低
-
哈希函數數量k:過多會增加計算開銷
-
元素數量n:實際插入的元素數
根據公式:最優哈希函數數量k ≈ (m/n)*ln2,工程中常用Guava庫自動計算這些參數。
?