1. 程式人生 > >大白話 強大的布隆過濾器演算法-極大降低儲存空間

大白話 強大的布隆過濾器演算法-極大降低儲存空間

     “寧可錯殺三千,絕不放過一個”,這是布隆過濾器的失誤型別金句。

1、什麼是布隆過濾器

       瞭解熟悉布隆過濾器,先從瞭解hash函式開始。最簡單說,一個數據經過hash函式計算後,會得到另一個輸出值。hash函式能給你的保證就是,相同的輸入值,經過計算後,一定得到相同的輸出值。但是不給你保證不同的輸入值,會得到不同的輸出值。梳理一下,hash函式的規則如下:

        1、當給雜湊函式傳入相同的輸入值時,返回的輸出值一定相同。

        2、當給雜湊函式傳入不同的輸入值時,返回的輸出值,可能不同,也可能相同。

        3、評判一個雜湊函式優劣,就是看對不同的輸入值,返回的輸出值是否均勻的分佈,最好的雜湊函式,就是儘可能保證不同的輸入值,能得到儘可能多不同的輸出值。也就是完美的雜湊函式,就是不同的輸入,得到不同的輸出,完全1對1。

        典型的雜湊函式有MD5,SHA1,SHA2等演算法。

        布隆過濾器,它類似一個聚合的hash函式。我們先說原理,待會舉例說一下,儘可能通俗易懂(堅信最好的理解,也就是最白話、最簡單的理解)。

        假設有個長度為m=1024 的bit 陣列,也就是一個佔用空間1kb的陣列。很明顯bit陣列的值只有0和1。我們有個雜湊函式,任何的輸入值(字串、boolean、物件),經過這個hash函式計算後,得到的輸出是個int整數(佔用16位,這裡其實為了瞭解原理,不用太關心佔位大小,大家可以忽略不關注)。

        布隆過濾器,就是利用一個bit陣列,多個不同的hash函式,比如我們有10個不同的hash函式,我給一個輸入值98,經過這是個hash函式計算後,得到輸出值是,打個比方,方便大家理解,剛好就是1024,1025,1026,1027,1028,1029,1030,1031,1032,1034,1035。然後這10個輸出值,我們分別對m也即是1024進行取模計算,得到0,1,2,3,...9,那麼,我們就把陣列0~9的位置塗黑,其實就是變成1。也就是輸入值98,在bit數組裡面,用位置0~9,是1來表示。下一個輸入109,可能就把11~20這10個位置塗黑變成1。

        這樣的實現就是,比如我們有10億個網址,就是黃賭毒的網址,我們要做個黑名單過濾。如果存入到記憶體或者資料庫,肯定需要很大的儲存空間。但我們就是先慢慢一個個讀取這10億個url,建立布隆過濾器,可以選擇用一個1mb或者1kb的bit陣列放在記憶體。當有個url過來,我們進行多個hash計算,如果這個url是在黑名單裡,那麼過濾器的bit陣列相應的位置一定都是1被塗黑的。如果這個url計算的位置上有一個是空白,未被塗黑,那麼它100%就不是黑名單之屬,可以放行。

     但是有個缺點也是失誤,比如bit陣列比較小,幾個url白名單計算後,全部都是黑的了。那麼任何url過來計算的位置,都是黑的,就被錯誤認為是黑名單,這就造成了開頭說的“寧可錯殺三千,絕不放過一個”,這樣一個火爆脾氣造成的失誤。非常嚴格。所以後文的使用場景就有得分析了。

2、布隆過濾器適合使用的場景

       布隆過濾器優缺點都很明顯,優點就是可以利用演算法優勢,使用計算,極大降低儲存空間。缺點就是有失誤率,不在過濾器原始表的資料,也可能被計算成原始表資料之一。

        這樣理解可能不是很好,換個說法:布隆過濾器,目標就是要基於過濾器已儲存生成的原始元資料,進行比較過濾,如果是在原始元資料集合裡面的,一定會被發現。基於這個特點,我們就可以做黑名單這樣的過濾器,存在黑名單原始元資料的,在布隆過濾器裡,是一定不能通過刷洗的。

         所以,這個演算法正確的使用場景是,利用它進行過濾遮蔽-禁止通行。黑名單過濾就是正確的使用場景,如果用來做白名單,那就進入了過濾器的失誤區,幾乎不可能做100%準確。比如白名單有原始資料1,2,3,4。資料44的計算也可能和4存在過濾器中有相同的值表現,44會被誤認為是4,白名單要做放行,那就放錯了。所以,布隆過濾器核心正確的使用就是進行過濾禁止,進行正確的否定。否定才是它所擅長的。