簡介
布隆過濾器適合大數據判重的場景,如網絡爬蟲中判斷一個URL是否已經爬取過,判斷一個用戶是否在黑名單中,判斷一個郵件是否是垃圾郵件,等等。
優點:占用空間小,效率高,簡而言之,就是以正確率換空間和時間。
缺點:有一定的誤判率,一個URL經過布隆過濾器判斷沒爬取過,那么一定沒爬取過,一個URL經過布隆過濾器判斷爬取過,可能並沒有爬取過,這種情況會有誤判。
布隆過濾器本身是基於位圖的,是對位圖的一種改進,位圖在java中的實現就是BitSet。
簡單使用
java中的Guava工具包提供了BloomFilter的實現。
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>27.1-jre</version>
</dependency>
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import java.util.ArrayList;
import java.util.List;
public class Client {
public static void main(String[] args) {
int size = 1_000_000;
BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size);
for (int i = 0; i < size; i++) {
bloomFilter.put(i);
}
for (int i = 0; i < size; i++) {
if (!bloomFilter.mightContain(i)) {
System.out.println("有壞人逃脫了");
}
}
List<Integer> list = new ArrayList<>(1000);
for (int i = size + 10000; i < size + 20000; i++) {
if (bloomFilter.mightContain(i)) {
list.add(i);
}
}
System.out.println("有誤傷的數量:" + list.size());
}
}
輸出結果為
有誤傷的數量:330
可以看到,不會有壞人逃脫,但會有誤傷,誤傷率大概為3%。
這種情況下大概要使用內存為7298440bit,約0.87M。
我們將誤傷率改為0.0003
BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, 0.0003);
誤傷數量為2,使用內存為16883499bit,約2.013M。