布隆過濾器如何防止Redis快取穿透?
布隆過濾器如何防止Redis快取穿透
兄弟們在學習快取穿透時,聽說解決快取穿透傳統方案之一就是使用布隆過濾器,那什麼是布隆過濾器呢?首先我們看看什麼是快取穿透!
一、什麼是快取穿透?
使用者查詢的資料在Redis中未命中,查詢資料庫也不存在,每次請求直接訪問資料庫,造成資料庫短時間內承受大量請求而崩掉。一般是由於黑客攻擊,出現非正常URL訪問。
二、什麼是布隆過濾器?
布隆過濾器實際上是一個很長的二進位制向量和一系列雜湊函式組成的概率性資料結構。
使用雜湊函式有兩個好處:1)雜湊函式無論輸入值的長度是多少,得到的輸出值長度固定 2)使元素分佈均勻,常見的雜湊函式:MD5、SHA-1
作用:主要用於判斷一個元素是否在一個集合中,0代表不存在,1代表存在。
特點:
- 高效插入和查詢,但不易刪除,同時返回結果可能存在誤判。
- 採用bitmap結構來儲存資料,相比於傳統的list、map、set效率更高,佔用空間更少。
假設一個元素佔1個位元組,使用傳統資料結構儲存10億資料需要900G記憶體空間。引入bitmap結構,僅需要120M記憶體空間,佔用空間極大減少。
三、布隆過濾器原理
3.1 存入過程
- 通過k個雜湊函式計算該資料,返回k個計算出的hash值
- 將計算出k個hash值對映到對應的k個二進位制的陣列下標
- 將k個下標的對應的二進位制資料改成1
根據上述圖示,"你好"就存到了布隆過濾器中,在下標為3、5、7位置組合表示 “你好” 這個資料。
3.2 查詢過程
布隆過濾器主要作用就是查詢一個數據是否在二進位制集合中,查詢過程如下:
- 通過k個雜湊函式計算該資料,返回k個計算出的hash值
- 通過hash值找到對應的二進位制的陣列下標
- 判斷:如果存在一處位置的二進位制資料是0,表明資料不存在。如果都是1,表明資料存在集合中。
查詢過程可能會出現誤判:
假如上圖沒有存"hello",只存了"你好",那麼用"hello"來查詢的時候,會判斷"hello"存在集合中。因為“你好”和“hello”的hash值是相同,就造成了誤判。
3.3 刪除過程
一般不能刪除布隆過濾器中的資料,因為布隆過濾器刪除操作有可能造成誤刪。
計算hash值時,可能會由於雜湊衝突造成同一個下標可能儲存了2個數據。如:圖中的"你好"和"hello",假如最終算出hash值相同,那麼它們會將同一個下標的二進位制資料改為1。這時想去刪除"你好",將下標為2中的二進位制資料由1改成了0,那麼我們是不是連"hello"都一起刪了。
四、布隆過濾器如何防止Redis快取穿透?
前面講了這麼多,終於回到主題上來了。
布隆過濾器會有一定概率誤判,但訪問一個數據如果布隆過濾器判斷不存在,說明資料一定不存在,就不會請求資料庫了,能夠有效避免大量無效請求來訪問資料庫
1)將資料庫所有的資料載入到布隆過濾器
2)查布隆過濾器(如果未命中直接結束)
3)查Redis快取資料(如果未命中查詢資料庫 )
4)查詢資料庫