Bloom Filter 布隆過濾器
hash function hash函式
通過計算得到一個資料的hash值的函式
md5、sha1……好像都是對一個資料反覆進行了大量的二進位制運算,比如:或、與……,具體實現看原始碼
Features:
- (在使用同一個hash function的前提下)相同的輸入有相同的輸出,不同輸入均勻分佈(但是不同的輸入也可能計算出的hash值是一樣的,因為輸入域是無限的 輸出域是固定數量(16位的16進位制)、固定資料的)
- hash function計算得出的hash值長度固定
- hash函式與輸入的順序無關,會均勻分佈,比如:有一個s域 0~99 經過hash函式計算後又 % array的size,就會在這個array陣列上均勻分佈
- 一個域均勻分佈,那麼它取模(%)後還是均勻分佈的
雜湊分佈是評判一個hash function優劣的標準,也就是說使用hash function計算出的陣列下標位置是會做到均勻分佈的,
但是雜湊分佈和陣列容量大小有關,隨著底層結構 陣列 的可使用容量的減少,會增大發生hash衝突的概率,所以需要使用負載因子來判斷何時需要resize陣列的容量
hash擴容 resize:
每次擴容都會是現在容量大小的2倍,那麼如果擴容到N的大小,那麼時間複雜度就是logN,但是擴容後還需要對原來的資料進行重新rehash,每次擴容的時間複雜度應該就是N了,那麼多次擴容的總時間複雜度就是N * logN
resize還可以後臺操作,不佔用主執行緒的時間
hash函式在大資料領域經常使用
布隆過濾器 Bloom Filter
作用:
解決一個數值是否存在某個範圍內,如果使用hashMap會造成很大的記憶體佔用。
比如:不安全網頁的黑名單包含100億個黑名單網頁,每個網頁的URL最多佔用64位元組。現在想要實現一種網頁過濾系統,可以根據網頁的URL判斷該網站是否在黑名單上,請設計該系統。要求該系統允許有萬分之一以下的判斷失誤率,並且使用的額外空間不要超過30G。
這個問題如果使用hashMap來儲存黑名單,有100億個URL,每個URL最多佔用64位元組,就是640G的記憶體空間,所以Bloom Filter就登場了。
Bloom Filter使用的是一個bitMap,即bit陣列,每一個bit都代表了一資料,所以資料的單位就從原來的byte位元組縮減到了bit
原理:
一個資料通過一系列的hash function,得到多個hash值,對這多個hash值進行計算,計算得到bitmap中的某個下標位置,然後將該下標的元素置為1。
如果在之後的計算中計算出的下標位置已經為1,再繼續置為1。
如果在之後查詢中,對一個資料使用k個hash function計算,計算得出的k個下標中有1個下標不是1,那麼這個資料不在Bloom Filter中,如果全為1,才在。因為如果一個資料在Bloom Filter中,它計算出的下標應該全為1才對。
計算邏輯:
使用計算出的hash值進行%取餘計算得到bitmap中的下標位置
(一般使用hash function對一個資料計算 計算得出陣列下標,然後在陣列中儲存資料 或者 標記為1,但是Bloom Filter不是這樣,
Bloom Filter使用了k個hash function,計算得出k個hash值,再對k個hash值進行計算得出陣列下標 標記為1,這整個過程就代表這個資料進到Bloom Filter裡來了。
所以bitmap就要很大,因為如果是100億個資料,每個資料都要使用k個hash function計算得出k個下標,如果bitmap容量比100億小,操作完後bitmap全1了 還查什麼,這失誤率不就100%了嘛。
所以也可以得出 可以通過調整hash function的個數 和 bitmap的容量 來得到失誤率。
bitmap容量多大合適呢?bitmap容量與 失誤率 和 hash function個數 有關)
公式:
Bloom Filter的大小m,失誤率p,樣本數量n,比如:樣本數量100億,失誤率萬分之一 即0.01%
根據公式計算出m=19.19n,向上取整為20n,即需要2000億個bit,也就是25GB。
hash function個數k
因為我們在確定布隆過濾器大小的過程中選擇了向上取整,所以還要用如下公式確定布隆過濾器真實的失誤率為
根據這個公式算出真實的失誤率為0.006%,這是比0.01%更低的失誤率,雜湊函式本身不佔用什麼空間,所以使用的空間就是bitMap的大小(即25GB),伺服器的記憶體都可以達到這個級別,所有要求達標。
優點:
節省空間佔用、查詢效率也快
缺點:
有一定失誤率、刪除困難
失誤率:因為hash function有不同的輸入也會有相同輸出的問題,所以會出現某個在黑名單中不存在的資料但是經過hash function計算後再計算出下標位置後發現該位置為1的情況
刪除困難:某個資料不在名單中了,將bitmap中的下標位置置為0了,但是由於其他資料在這個下標位置置為1過,現在是0了,就會造成之後查詢時,原本在黑名單中的這個下標的資料訪問時,由於已經是0了,就代表不在黑名單中,所以這個資料就可以和正常資料一樣任意訪問了,產生資料不安全的問題
(與hashMap不同的是hashMap使用hash function計算出hash值後再計算出下標位置後會儲存資料,所以發生hash碰撞後因為資料的不同不會失誤的覆蓋掉不同的資料,而Bloom Filter使用hash function計算出hash值後再計算出下標位置後會置為1,所以之後查詢時,不同的資料使用hash function計算出hash值後再計算出下標位置後無法判斷是否是相同的資料置為1的,所以就會發生誤判,存在失誤率)
使用場景:
- 在大資料量的場景下 比如:上億資料,計算某個資料是否存在
- 快取穿透
問:
為什麼使用多個hash function?是為了使用多個結果來證明某個資料存在嗎?還是其他別的原因?
一個資料使用多個hash function後,計算出來的hash值不一樣嗎?
多個hash函式的邏輯是不同的,比如:雖然是相同的輸入必會有相同的輸出,但也只是在使用同一種hash function的前提下,如果對同一個資料分別使用md5、sha1計算出的hash值就是不一樣的。
tips: Bloom Filter因為使用hash function,而且不像hashMap一樣儲存了資料,只是將制定位置置為了1,所以會因為hash衝突有失誤率,在建模時,就需要根據想要達到的失誤率來定義bitmap的大小、hash function的個數。
可供使用的第三方:
guava
redis(需要自己建立bitmap、定義bitmap的大小、hash function的個數、hash function的邏輯實現、手動標記bitmap中的下標位置)
hint:
單點登入CAS時,每個伺服器請求統一認證伺服器後,會在本地伺服器上快取cookie,因為如果每次請求都去請求統一認證伺服器 對伺服器有壓力,這就和平時使用瀏覽器訪問某個網站時一樣,第一次請求伺服器並快取,第二次後就從快取中獲取
相關文章
- 布隆過濾器(Bloom Filter)過濾器OOMFilter
- 布隆過濾器 Bloom Filter過濾器OOMFilter
- 布隆過濾器(Bloom Filter)詳解過濾器OOMFilter
- 布隆過濾器(Bloom Filter)的java實現過濾器OOMFilterJava
- 探索C#之布隆過濾器(Bloom filter)C#過濾器OOMFilter
- 雜湊表擴充套件—布隆過濾器(Bloom Filter)套件過濾器OOMFilter
- Xor過濾器:比布隆Bloom過濾器更快,更小過濾器OOM
- 快取問題(二) 布隆過濾器(Bloom Filter) 介紹和原理快取過濾器OOMFilter
- [大資料量]布隆過濾器(Bloom Filter)適用型別以及具體示例大資料過濾器OOMFilter型別
- 布隆過濾器過濾器
- 大白話布隆過濾器過濾器
- Guava的布隆過濾器Guava過濾器
- Redis-布隆過濾器Redis過濾器
- 布隆過濾器的概述過濾器
- 淺談布隆過濾器過濾器
- Redis 中的布隆過濾器Redis過濾器
- Redis 應用-布隆過濾器Redis過濾器
- PHP實現布隆過濾器PHP過濾器
- 布隆過濾器 與 Redis BitMap過濾器Redis
- 5分鐘掌握布隆過濾器過濾器
- victoriaMetrics庫之布隆過濾器過濾器
- 還有人不懂布隆過濾器嗎?過濾器
- Hbase 布隆過濾器BloomFilter介紹過濾器OOMFilter
- 布隆過濾器-使用場景的思考過濾器
- Redis詳解(十三)------ Redis布隆過濾器Redis過濾器
- 從快取穿透聊到布隆過濾器快取穿透過濾器
- 演算法(3)---布隆過濾器原理演算法過濾器
- Redis布隆過濾器分析與總結Redis過濾器
- 布隆過濾器的原理及應用過濾器
- 詳解布隆過濾器原理與實現過濾器
- 面試官問:什麼是布隆過濾器?面試過濾器
- LevelDB 學習筆記1:布隆過濾器筆記過濾器
- 品味布隆過濾器的設計之美過濾器
- 實現布隆過濾器的三種方式過濾器
- 那些有趣的演算法之布隆過濾器演算法過濾器
- 布隆過濾器實戰【防止快取擊穿】過濾器快取
- Redis快取穿透解決方案--布隆過濾器Redis快取穿透過濾器
- 布隆過濾器解決快取穿透問題過濾器快取穿透