BloomFilter算法及其适用场景

  BloomFilter是利用类似位图或者位集合数据结构来存储数据,利用位数组来简洁的表示一个集合,并且能够快速的判断一个元素是不是已经存在于这个集合。因为基于Hash来计算数据所在位置,所以BloomFilter的添加和查询操作都是O(1)的。因为存储简洁,这种数据结构能够利用较少的内存来存储海量的数据。那么,还有这种时间和空间两全其美的算法?当然不是,BloomFilter正是它的高效(使用Hash)带来了它的判断不一定是正确的,也就是说准确率不是100%。因为再好的Hash都是存在冲突的,这样的话同一个位置可能被多次置1。这样再判断的时候,有可能一个不存在的数据就会误判成存在。但是判断存在的数据一定是存在的。这里需要注意的是这里的Hash和HashMap不同,HashMap可以使用开放定址发、链地址法来解决冲突,因为HashMap是有Key-Value结构的,是可逆的,可以定位。但是Hash是不可逆的,所以不能够解决冲突。虽然BloomFilter不是100%准确,但是可以通过调节参数,使用Hash函数的个数,位数组的大小来降低失误率。这样调节完全可以把失误率降低到接近于0。可以满足大部分场景了。

  关于BloomFilter的理论请参考:

  http://blog.csdn.net/jiaomeng/article/details/1495500

  https://en.wikipedia.org/wiki/Bloom_filter

  适用场景:BloomFilter一般适用于大数据量的对精确度要求不是100%的去重场景。

  爬虫链接的去重:大的爬虫系统有成千上万的链接需要去爬,而且需要保证爬虫链接不能循环。这样就需要链接列表的去重。把链接Hash后存放在BitSet中,然后在爬取之前判断是否存在。

  网站UV统计:一般同一个用户的多次访问是要过滤掉的,一般大型网站的UV是巨大的,这样使用BloomFilter就能较高效的实现。

结合Redis

  前面说的BloomFilter算法是单机的,可以使用JDK自带的BitSet来实现。但是拥有大数据量的系统绝不是一台服务器,所以需要多台服务器共享。结合Redis的BitMap就能够完美的实现这一需求。利用redis的高性能以及通过pipeline将多条bit操作命令批量提交,实现了多机BloomFilter的bit数据共享。唯一需要注意的是redis的bitmap只支持2^32大小,对应到内存也就是512MB,数组的下标最大只能是2^32-1。不过这个限制我们可以通过构建多个redis的bitmap通过hash取模的方式分散一下即可。万分之一的误判率,512MB可以放下2亿条数据。

实践

  使用了Github上两个开源的实现测试了一下,是基于JDK BitSet实现的。

  开源代码:https://github.com/MagnusS/Java-BloomFilter

         https://github.com/Baqend/Orestes-Bloomfilter

  测试结果(在本地测试,耗时是每条数据的耗时):

  

  然后在java-bloomFilter的基础上修改了源代码,在有5个节点的Redis集群上做了一下测试。

  测试结果:

  初始化:173070
  插入数据:173070
  查询数据:173070
  耗时:350261ns
  内存:326KB
  失误率:0.00%

  可以看到结合Redis的BloomFilter算法的性能还是比较好的。

  Redis+BloomFilter测试源代码:https://github.com/wxisme/redis-bloomFilter

  

基于Redis的BloomFilter算法去重的更多相关文章

  1. [转载]基于Redis的Bloomfilter去重(附Python代码)

    前言: “去重”是日常工作中会经常用到的一项技能,在爬虫领域更是常用,并且规模一般都比较大.去重需要考虑两个点:去重的数据量.去重速度.为了保持较快的去重速度,一般选择在内存中进行去重. 数据量不大时 ...

  2. 基于Redis的Bloomfilter去重(转载)

    转载:http://blog.csdn.net/bone_ace/article/details/53107018 前言 “去重”是日常工作中会经常用到的一项技能,在爬虫领域更是常用,并且规模一般都比 ...

  3. 基于Redis的分布式锁和Redlock算法

    1 前言 前面写了4篇Redis底层实现和工程架构相关文章,感兴趣的读者可以回顾一下: Redis面试热点之底层实现篇-1 Redis面试热点之底层实现篇-2 Redis面试热点之工程架构篇-1 Re ...

  4. 身为一枚优秀的程序员必备的基于Redis的分布式锁和Redlock算法

    1 前言 今天开始来和大家一起学习一下Redis实际应用篇,会写几个Redis的常见应用. 在我看来Redis最为典型的应用就是作为分布式缓存系统,其他的一些应用本质上并不是杀手锏功能,是基于Redi ...

  5. 基于redis分布式缓存实现

    Redis的复制功能是完全建立在之前我们讨论过的基 于内存快照的持久化策略基础上的,也就是说无论你的持久化策略选择的是什么,只要用到了Redis的复制功能,就一定会有内存快照发生,那么首先要注意你 的 ...

  6. 基于redis实现可靠的分布式锁

    什么是锁 今天要谈的是如何在分布式环境下实现一个全局锁,在开始之前先说说非分布式下的锁: 单机 – 单进程程序使用互斥锁mutex,解决多个线程之间的同步问题 单机 – 多进程程序使用信号量sem,解 ...

  7. 基于redis排行榜的实战总结

    前言: 之前写过排行榜的设计和实现, 不同需求其背后的架构和设计模型也不一样. 平台差异, 有的立足于游戏平台, 为多个应用提供服务, 有的仅限于单个游戏.排名范围差异, 有的面向全局排名, 有的只做 ...

  8. 基于Redis的分布式锁真的安全吗?

    说明: 我前段时间写了一篇用consul实现分布式锁,感觉理解的也不是很好,直到我看到了这2篇写分布式锁的讨论,真的是很佩服作者严谨的态度, 把这种分布式锁研究的这么透彻,作者这种技术态度真的值得我好 ...

  9. 基于redis的分布式锁(转)

    基于redis的分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分 ...

随机推荐

  1. nload 实时网速查看

    nload eth0 -u K Device eth0 [192.168.0.33] (1/1):=================================================== ...

  2. RTL8710 Flasher

    https://bitbucket.org/rebane/rtl8710_openocd/ rtl8710_openocd / script / rtl8710.ocd # # OpenOCD scr ...

  3. ELK——Elasticsearch 搭建集群经验

    本文内容 背景 ES集群中第一个master节点 ES slave节点 本文总结 Elasticsearch(以下简称ES)搭建集群的经验.以 Elasticsearch-rtf-2.2.1 版本为例 ...

  4. [ay原创作品]用wpf写了个模仿36Kr网站登录背景的效果

    这里我借鉴了,上周比较火的一个前端文章,人家用js去写的,地址 自己用wpf也写了一个,但是它的  粒子比较,然后连线算法真的很差,他创建了一个加入鼠标点的集合,2个集合进行比较,并且粒子会向鼠标靠近 ...

  5. Linux 的启动流程(转)

    原文链接:http://blog.jobbole.com/46078/ 半年前,我写了<计算机是如何启动的?>,探讨BIOS和主引导记录的作用. 那篇文章不涉及操作系统,只与主板的板载程序 ...

  6. VS2010安装失败解决办法

    1. 运行regedit打开注册表: 2. 找到HKEY_LOCAL_MACHINE\SOFWARE\ Microsoft\ Internet Explorer\ MAIN: 3. MAIN子键的权限 ...

  7. JS回到顶部代码小记

    HTML: <div id="goTop"> <a href="#top"><img src="~/Content/th ...

  8. 阅读《Effective C++》系列

    <Effective C++>条款07:为多态基类声明virtual析构函数 这样做主要是为了防止内存泄漏,见我hexo博客. C++的虚析构函数 <Effective C++> ...

  9. Python Base HTTP Server

    import BaseHTTPServer import cgi, random, sys MESSAGES = [ "That's as maybe, it's still a frog. ...

  10. 从远程服务器数据库中同步数据到本地数据库 sql server 2008 开启分布

    控制面板\所有控制面板项\管理工具 打开“管理工具――组件服务”,以此打开“组件服务――计算机”,在“我的电脑”上点击右键.在MSDTC选项卡中,点击“安全配置”按钮. 在安全配置窗口中做如下设置: ...