1. 程式人生 > 其它 >大資料和空間限制 | 認識布隆過濾器

大資料和空間限制 | 認識布隆過濾器

### 布隆過濾波器

本質上來講,布隆過濾器是一種資料結構,是一種低成本、高效能、巧妙的概率型資料結構(probabilistic data structure),可以高效地更新和查詢,可以用來實現大資料量情況下的 **“某樣東西一定不存在或者可能存在”**。

這種看似不能夠100%的告訴我們準確結果的資料結構,由於其低成本的實現,其實已經大大滿足了我們的實際生產環境的需求,能夠幫助我們快速在大資料量的情況下做出可靠的反應。

布隆過濾器的核心技術實現就是`bit array`,由於`bit`只能代表0和1,因此這就是布隆過濾器高效能和低成本的關鍵。

![bitmap.jpg](https://upload-images.jianshu.io/upload_images/15984870-7fa4f62456fa65d9.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

### 實際場景

假設我們有一個不安全網頁的黑名單,數量為100億個,每個網頁的URL最多佔用64B。我們現在需要實現一個黑名單過濾系統,用來判斷請求訪問的地址是不是屬於黑名單之內。

### 要求

1. 該系統允許有0.01%的失誤率。

2. 使用的額外空間不超過30GB。

### 思考

如果我們使用資料庫或者`hash table`來直接儲存100億個黑名單網頁,就需要640GB的儲存容量,這顯然不符合要求。

### 解決思路

為了解決這個問題,我們需要使用布隆過濾器的知識。

#### `hash`函式,亦稱雜湊函式

1. 典型的雜湊函式都有無限的輸入值域;

2. 當給雜湊函式輸入的內容一致時,則返回值一樣;

3. 當給雜湊函式輸入的值不一樣時,返回值有可能一樣,也可能不一樣, 但是返回值域都會分佈在S上;

4. 海量不同的輸入值經過雜湊函式的計算,得到的返回值都會均勻的分佈在S上;

使用好布隆過濾器的關鍵是**雜湊函式的個數**、**`bit array`的大小**。

布隆過濾器的大小由以下公式確定:

![image](https://upload-images.jianshu.io/upload_images/15984870-80bf374c13b895ee?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

根據公式計算得出,m=19.19n,我們向上取整為20n,即需要2000億個bit,也就是25GB。

雜湊函式的個數由以下公式計算得出:

![image](https://upload-images.jianshu.io/upload_images/15984870-a213b04ae347a190?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

雜湊函式的個數為:k=14

因為我們在計算布隆過濾器大小時,選擇了向上取整,因此還需要用如下公式確定布隆過濾器的真實失誤率:

![image](https://upload-images.jianshu.io/upload_images/15984870-2c88821ede896b80?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

真實失誤率為0.006%,這是比0.01%更低的失誤率,因此呢,該方法是符合實際要求的。

布隆過濾器失誤率分析:假設布隆過濾器中的k個雜湊函式足夠好且各自獨立,每個輸入物件都等概率的雜湊到bitmap中m個bit中任意k個位置,且與其他元素被雜湊到哪裡無關。那麼對於一個bit來說,一個輸入物件在被k個雜湊函式雜湊後,這個位置依然沒有被塗黑的概率為:

![image](https://upload-images.jianshu.io/upload_images/15984870-fa38cc08a99e7e04?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

經過n個輸入物件後,這個位置依然沒有被塗黑的概率為:

![image](https://upload-images.jianshu.io/upload_images/15984870-7b79d32e8548b1a9?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

那麼被塗黑的概率就為:

![image](https://upload-images.jianshu.io/upload_images/15984870-2046c43b30706c06?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

那麼在檢查階段,檢查k個位置都為黑的概率為:

![image](https://upload-images.jianshu.io/upload_images/15984870-b2e66d4e68c6c45b?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

在x->0時,(1+x)^(1/x)->e,上面等式的右邊可以認為m很大的數,所以-1/m->0,所以簡化為:

![image](https://upload-images.jianshu.io/upload_images/15984870-ab833af15e42db8c?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

布隆過濾器會有誤報,但是我們可以對誤報樣本建立白名單來防止誤報。

布隆過濾器對於大資料相關的題目能夠很好的解決。