BloomFilter & Hyperloglog 去重 & 统计

 

去重小结

最近在做爬虫的时候,遇到了去重的问题,关于去重,有很多地方可以做,比如

  • 内存级别,利用 hashmap,准确,性能好但是内存有限
  • 数据库,利用唯一键,准确,存储量大但是性能差
  • 内存级别 BloomFilter,利用 bitmap,性能好,存储量比 hashmap 大得多,但是有误差
    实际使用的时候要根据场景去 tradeoff,没有最好的办法,只有最合适的办法

基数统计

同样,当我们需要统计个数时,也有很多办法,比如

  • 内存级别 hashset,准确,但是存储量跟数据量成正比,原始数据还存在
  • 数据库也可以做,准确但性能较差
  • 内存级别,Hyperloglog,只需少量内存即可,但误差较大
    如果我们单单只是技术统计,对准确率要求并不高,可以采取 Hyperloglog,只不过没有记录原始数据,但这恰好为节省内存埋下了伏笔

BloomFilter 原理

有 k 个 hash 函数,对每一个 key 进行 hash 函数计算大小,将 m 位 0 字符串在对应的取余赋值为 1 即可

检查是否存在:计算 key 对应的 k 个 hash值在字符串中的位是否全为 1,如果是,则有可能存在,否则肯定不存在

例子, key = bloom hashcode = [1, 2, 3]

011100000000000000000

接下来 key = filter 经过同样的 hash 计算 hashcode = [2,4,6]
经过计算不存在,则放入

011101000000000000000

实际应用中如何选择 m,k,f 的大小,有一个数据公式推导,大家可以自行 Google

HyperLogLog 原理

使用概率的原理
这篇文章还不错 https://blog.csdn.net/firenet1/article/details/77247649
总结一下,就是说,我们丢硬币的场景,第一次出现正面,之前都是反面的概率与实验次数有一个关系 n = 2^k,那么我们将 key 映射成 二进制hashcode,0001010, 该过程完全随机,那么 n 就等于 2^4,也就是说试验次数达到 8,但误差较大,所以我们采用多个映射取平均,这样误差就会变小
但是这样的误差很大

大家可以看看 stream-lib 里边的实现,很经典

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值