Guava布隆過濾器實戰應用


布隆過濾器

簡介:本質上布隆過濾器是一種數據結構,比較巧妙的概率型數據結構(probabilistic data structure),特點是高效地插入和查詢,可以用來告訴你 “某樣東西一定不存在或者可能存在”

判斷一個元素是不是在一個集合里,一般想到的是將所有元素保存起來,然后通過比較來確定。鏈表、平衡二叉樹、散列表,或者是把元素放到數組或鏈表里,都是這種思路。以上三種結構的檢索時間復雜度分別為O(n), O(logn), O(n/k),O(n),O(n)。而布隆過濾器(Bloom Filter)也是用於檢索一個元素是否在一個集合中,它的空間復雜度是固定的常數O(m),而檢索時間復雜度是固定的常數O(k)。相比而言,有1%誤報率和最優值k的布隆過濾器,每個元素只需要9.6個比特位--無論元素的大小。這種優勢一方面來自於繼承自數組的緊湊性,另外一方面來自於它的概率性質。1%的誤報率通過每個元素增加大約4.8比特,就可以降低10倍

應用場景:主要是解決大規模數據下不需要精確過濾的場景,如檢查垃圾郵件地址,爬蟲URL地址去重,解決緩存穿透問題等。

在緩存穿透問題上,使用布隆過濾器判斷數據是否存在,不存在直接返回
海量數據去重:爬蟲系統中對成千上萬的url的去重等
郵箱系統的垃圾郵件過濾功能

 

實際測試代碼

import java.util.ArrayList;
import java.util.List;

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;

public class Bloom {
    
    private static int size = 1000000;
    // private static BloomFilter<CharSequence> bloomFilter =
    // BloomFilter.create(Funnels.stringFunnel(Charset.forName("utf-8")),
    private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, 0.0001);

    public static void main(String[] args) {

        for (int i = 0; i < size; i++) {
            bloomFilter.put(i);
        }
        System.out.println("write over!");

        for (int i = 0; i < size; i++) {
            if (!bloomFilter.mightContain(i)) {
                System.err.println("有逃犯越獄了");
            }
        }

        List<Integer> list = new ArrayList<Integer>();
        for (int i = size + 10000; i < size + 20000; i++) {
            if (bloomFilter.mightContain(i)) {
                list.add(i);
            }
        }
        System.out.println("誤傷數:" + list.size());
    }
    // 可能存在誤判,當布隆過濾器說某個值存在時,這個值可能不存在;當它說不存在時,那就肯定不存在
}
<dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>28.0-jre</version>
</dependency>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM