1. 程式人生 > 其它 >布隆過濾器解決快取穿透問題

布隆過濾器解決快取穿透問題

背景:很多商城,商品詳情的連結格式:https://item.jd.com/100005786822.html,不同的商品詳情的連結不一樣的地方在於商品編號,如,我有個商品1002002,那麼商品詳情的連結為https://item.jd.com/1002002.html;

當我們訪問商品詳情連結時,後臺的邏輯:先從redis中查詢該商品,如果不存在,再查資料庫。我們分析一下,感覺邏輯沒問題,但是,如果訪問的商品不存在呢?如果我寫個死迴圈去呼叫不存在的商品詳情會怎麼

樣,如下程式碼:

如果後臺沒作特別處理,這樣資料庫會掛掉,進而系統也會掛掉?

怎麼解決這個問題呢?那就要用到布隆過濾器了:

布隆過濾器由一個二進位制的陣列組成:我們假設總共商品只有3個,分別為A,B,C 布隆過濾器的陣列長度是10,初始化時,每個索引對應的值都是0,因為二進位制不是0就是1:

現在將所有商品初始化進布隆過濾器,如A,先經過一個演算法,得出A在陣列哪個索引的值為1,然後又經過另一個演算法,得出A在陣列哪個索引值為1,最後再經過一次不同的演算法得到A在哪個索引的值為1;

假如經過三次計算,A在索引1,3,5的值都為1;此時的陣列:

同理,如果B商品經過三次計算,在0,3,7的值為1,因為索引3的值已經是1了,所以索引3不用再變更:

假如C商品經過計算得到1,4,5的值為1

至此,布隆過濾器初始化完畢,此時發現索引2,8,9的值都是0,證明沒有商品命中,現在如果被人惡意攻擊,傳了一個商品D,

經過三次計算,假如結果是0,2,7的結果是1,但布隆過濾器中索引2的值是0,這就說明了布隆過濾器沒有這個商品,因此沒有命中商品直接返回前端即可;

假如另一個商品E經過計算,索引0,1,3的值為1,通過布隆過濾器對比,發現,命中了,但此時,商品不一定存在,將會放行,先查redis,redis沒有命中再查資料庫;

上面就是布隆過濾器的原理了,通過分析,我們只要陣列夠大,計算次數過多,這樣過濾不存在商品的概率就越大;

總結布隆過濾器的特點:沒命中,肯定不存在,命中,不一定存在;

開發中使用:redisson框架實現了該功能,提供了一個初始化布隆過濾器陣列大小的方法,還有一個add商品到布隆過濾器的方法,以及判斷某個值在不在過濾器的方法;

提示:布隆過濾由於是二進位制的陣列,因此一個長度一億的布隆過濾器也不會佔用多大的記憶體,詳細,一個int型別的數字都32位了