使用Google BloomFilter 對爬蟲url集進行去重

生成 url 文件

#!/usr/bin/env bash

file='./bigFile.txt'
urlPre='https://blog.csdn.net/u010979642/'
[ $1 ] && count=$1 || count=10

for num in $(seq 1 ${count})
do
  # 隨機生成 count 以內的隨機數
  randomNum=$(($RANDOM%${count}))
  echo ${urlPre}${randomNum} >> ${file}
done

 

引入maven依賴

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>27.0.1-jre</version>
</dependency>

 

使用 BloomFilter 對url集進行去重

public static void main(String[] args) {
    long start = System.currentTimeMillis();

    String sourceFile = "C:\\Users\\answer\\Desktop\\bigFile.txt";

    // 初始化一個存儲String數據的布隆過濾器
    // expectedInsertions: 預估的元素個數, fpp: 誤判率, 默認值0.03, 誤判率越低所要求的內存越大
    BloomFilter<CharSequence> bloomFilter = BloomFilter.create(
        Funnels.stringFunnel(Charset.forName("utf-8")), 1000000, 0.00001);
    Set<String> urls = Sets.newHashSet();

    try (BufferedReader bufferedReader = new BufferedReader(new FileReader(sourceFile))) {
        String line;

        while ((line = bufferedReader.readLine()) != null) {
            if (!bloomFilter.mightContain(line)) {
                bloomFilter.put(line);
                urls.add(line);
            } else {
                System.out.println(String.format("line=[%s]已經存在", line));
            }
        }

        long end = System.currentTimeMillis();

        System.out.println(
			String.format("共耗時[%d]秒, 去重後個數=[%d], urls=[%d]", 
				(end - start) / 1000, 
				bloomFilter.approximateElementCount(),
				urls.size()
			)
        );

    } catch (IOException e) {
        e.printStackTrace();
    }
}

 

loomFilter<User> bloomFilter = BloomFilter.create(
                (from, into) -> into.putString(from.getUserName(), Charsets.UTF_8), 
                10000, 
                0.01);

 

Bloom Filter的應用

  • cerberus在收集監控數據的時候, 有的系統的監控項量會很大, 需要檢查一個監控項的名字是否已經被記錄到db過了, 如果沒有的話就需要寫入db.

  • 爬蟲過濾已抓到的url就不再抓,可用bloom filter過濾

  • 垃圾郵件過濾。如果用哈希表,每存儲一億個 email地址,就需要 1.6GB的內存(用哈希表實現的具體辦法是將每一個 email地址對應成一個八字節的信息指紋,然後將這些信息指紋存入哈希表,由於哈希表的存儲效率一般只有 50%,因此一個 email地址需要佔用十六個字節。一億個地址大約要 1.6GB,即十六億字節的內存)。因此存貯幾十億個郵件地址可能需要上百 GB的內存。而Bloom Filter只需要哈希表 1/8到 1/4 的大小就能解決同樣的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章