使用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 的大小就能解决同样的问题。

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