过滤器使用场景:

比如有如下几个需求:

1.原本有10亿个号码,现在又来了10万个号码,要快速准确判断这10万个号码是否在10亿个号码库中?
  解决办法一:将10亿个号码存入数据库中,进行数据库查询,准确性有了,但是速度会比较慢。
  解决办法二:将10亿号码放入内存中,比如Redis缓存中,这里我们算一下占用内存大小:10亿*8字节=8GB,通过内存查询,准确性和速度都有了,但是大约8gb的内存空间,挺浪费内存空间的。
2.接触过爬虫的,应该有这么一个需求,需要爬虫的网站千千万万,对于一个新的网站url,我们如何判断这个url我们是否已经爬过了?
解决办法还是上面的两种,很显然,都不太好。
3.同理还有垃圾邮箱的过滤。
  那么对于类似这种,大数据量集合,如何准确快速的判断某个数据是否在大数据量集合中,并且不占用内存,过滤器应运而生了。

布隆过滤器(Bloom Filter)

布隆过滤器:一种数据结构(bitmap),是由一串很长的二进制向量组成,可以将其看成一个二进制数组。既然是二进制,那么里面存放的不是0,就是1,但是初始默认值都是0。

1.添加数据
当要向布隆过滤器中添加一个元素key时,我们通过多个hash函数,算出一个值,然后将这个值所在的方格置为1。
2.如何判断是否存在
将这个新的数据通过上面自定义的几个哈希函数,分别算出各个值,然后看其对应的地方是否都是1,如果存在一个不是1的情况,那么我们可以说,该新数据一定不存在于这个布隆过滤器中。
反过来说,如果通过哈希函数算出来的值,对应的地方都是1,那么我们能够肯定的得出:这个数据一定存在于这个布隆过滤器中吗?
答案是否定的,因为多个不同的数据通过hash函数算出来的结果是会有重复的,所以会存在某个位置是别的数据通过hash函数置为的1。
我们可以得到一个结论:布隆过滤器可以判断某个数据一定不存在,但是无法判断一定存在。

比如下图的元素3,其实不存在,但是hash结果后的值,被元素1和元素2设置成1。

3.布隆过滤器优缺点

优点:优点很明显,二进制组成的数组,占用内存极少,并且插入和查询速度都足够快。
缺点:随着数据的增加,误判率会增加;还有无法判断数据一定存在;另外还有一个重要缺点,无法删除数据。

1.将算法和bitmap数据放在client
2.算法在client,bitmap数据在redis
3.讲算法和bitmap数据都放在redis

升级版的布隆过滤器(Counting Bloom Filter)

原理就是把位图的位 升级为计数器(Counter). 添加元素, 就给对应的Counter分别+1; 删除元素, 就给对应的Counter分别减一. 用多出几倍存储空间的代价, 来实现删除功能

布谷鸟过滤器(Cuckoo filter)

为了解决布隆过滤器不能删除元素的问题, 论文《Cuckoo Filter:Better Than Bloom》作者提出了布谷鸟过滤器。相比布谷鸟过滤器,布隆过滤器有以下不足:查询性能弱、空间利用效率低、不支持反向操作(删除)以及不支持计数。

查询性能弱是因为布隆过滤器需要使用多个 hash 函数探测位图中多个不同的位点,这些位点在内存上跨度很大,会导致 CPU 缓存行命中率低。

空间效率低是因为在相同的误判率下,布谷鸟过滤器的空间利用率要明显高于布隆,空间上大概能节省 40% 多。不过布隆过滤器并没有要求位图的长度必须是 2 的指数,而布谷鸟过滤器必须有这个要求。从这一点出发,似乎布隆过滤器的空间伸缩性更强一些。

不支持反向删除操作这个问题着实是击中了布隆过滤器的软肋。在一个动态的系统里面元素总是不断的来也是不断的走。布隆过滤器就好比是印迹,来过来就会有痕迹,就算走了也无法清理干净。比如你的系统里本来只留下 1kw 个元素,但是整体上来过了上亿的流水元素,布隆过滤器很无奈,它会将这些流失的元素的印迹也会永远存放在那里。随着时间的流失,这个过滤器会越来越拥挤,直到有一天你发现它的误判率太高了,不得不进行重建。

布谷鸟哈希
最简单的布谷鸟哈希结构是一维数组结构,会有两个 hash 算法将新来的元素映射到数组的两个位置。如果两个位置中有一个位置为空,那么就可以将元素直接放进去。但是如果这两个位置都满了,它就随机踢走一个,然后自己霸占了这个位置。

p1 = hash1(x) % l
p2 = hash2(x) % l
  • 1
  • 2

不同于布谷鸟的是,布谷鸟哈希算法会帮这些受害者(被挤走的蛋)寻找其它的窝。因为每一个元素都可以放在两个位置,只要任意一个有空位置,就可以塞进去。所以这个伤心的被挤走的蛋会看看自己的另一个位置有没有空,如果空了,自己挪过去也就皆大欢喜了。但是如果这个位置也被别人占了呢?好,那么它会再来一次「鸠占鹊巢」,将受害者的角色转嫁给别人。然后这个新的受害者还会重复这个过程直到所有的蛋都找到了自己的巢为止。

布谷鸟哈希的问题
但是会遇到一个问题,那就是如果数组太拥挤了,连续踢来踢去几百次还没有停下来,这时候会严重影响插入效率。这时候布谷鸟哈希会设置一个阈值,当连续占巢行为超出了某个阈值,就认为这个数组已经几乎满了。这时候就需要对它进行扩容,重新放置所有元素。

还会有另一个问题,那就是可能会存在挤兑循环。比如两个不同的元素,hash 之后的两个位置正好相同,这时候它们一人一个位置没有问题。但是这时候来了第三个元素,它 hash 之后的位置也和它们一样,很明显,这时候会出现挤兑的循环。不过让三个不同的元素经过两次 hash 后位置还一样,这样的概率并不是很高,除非你的 hash 算法太挫了。

布谷鸟哈希算法对待这种挤兑循环的态度就是认为数组太拥挤了,需要扩容(实际上并不是这样)

优化

上面的布谷鸟哈希算法的平均空间利用率并不高,大概只有 50%。到了这个百分比,就会很快出现连续挤兑次数超出阈值。这样的哈希算法价值并不明显,所以需要对它进行改良。

改良的方案之一是增加 hash 函数,让每个元素不止有两个巢,而是三个巢、四个巢。这样可以大大降低碰撞的概率,将空间利用率提高到 95%左右。

另一个改良方案是在数组的每个位置上挂上多个座位,这样即使两个元素被 hash 在了同一个位置,也不必立即「鸠占鹊巢」,因为这里有多个座位,你可以随意坐一个。除非这多个座位都被占了,才需要进行挤兑。很明显这也会显著降低挤兑次数。这种方案的空间利用率只有 85%左右,但是查询效率会很高,同一个位置上的多个座位在内存空间上是连续的,可以有效利用 CPU 高速缓存。

所以更加高效的方案是将上面的两个改良方案融合起来,比如使用 4 个 hash 函数,每个位置上放 2 个座位。这样既可以得到时间效率,又可以得到空间效率。这样的组合甚至可以将空间利用率提到高 99%,这是非常了不起的空间效率。

布谷鸟过滤器

布谷鸟过滤器和布谷鸟哈希结构一样,它也是一维数组,但是不同于布谷鸟哈希的是,布谷鸟哈希会存储整个元素,而布谷鸟过滤器中只会存储元素的指纹信息(几个bit,类似于布隆过滤器)。这里过滤器牺牲了数据的精确性换取了空间效率。正是因为存储的是元素的指纹信息,所以会存在误判率,这点和布隆过滤器如出一辙。

首先布谷鸟过滤器还是只会选用两个 hash 函数,但是每个位置可以放置多个座位。这两个 hash 函数选择的比较特殊,因为过滤器中只能存储指纹信息。当这个位置上的指纹被挤兑之后,它需要计算出另一个对偶位置。而计算这个对偶位置是需要元素本身的,我们来回忆一下前面的哈希位置计算公式。

fp = fingerprint(x)
p1 = hash1(x) % l
p2 = hash2(x) % l
  • 1
  • 2
  • 3

我们知道了 p1 和 x 的指纹,是没办法直接计算出 p2 的。

特殊的 hash 函数

布谷鸟过滤器巧妙的地方就在于设计了一个独特的 hash 函数,使得可以根据 p1 和 元素指纹 直接计算出 p2,而不需要完整的 x 元素。

fp = fingerprint(x)
p1 = hash(x)
p2 = p1 ^ hash(fp)  // 异或
  • 1
  • 2
  • 3

从上面的公式中可以看出,当我们知道 fp 和 p1,就可以直接算出 p2。同样如果我们知道 p2 和 fp,也可以直接算出 p1 —— 对偶性。

p1 = p2 ^ hash(fp)
  • 1

所以我们根本不需要知道当前的位置是 p1 还是 p2,只需要将当前的位置和 hash(fp) 进行异或计算就可以得到对偶位置。而且只需要确保 hash(fp) != 0 就可以确保 p1 != p2,如此就不会出现自己踢自己导致死循环的问题。

也许你会问为什么这里的 hash 函数不需要对数组的长度取模呢?实际上是需要的,但是布谷鸟过滤器强制数组的长度必须是 2 的指数,所以对数组的长度取模等价于取 hash 值的最后 n 位。在进行异或运算时,忽略掉低 n 位 之外的其它位就行。将计算出来的位置 p 保留低 n 位就是最终的对偶位置。


http://www.taodudu.cc/news/show-6569972.html

相关文章:

  • 过滤器理解
  • 什么是过滤器?什么时候使用过滤器?如何使用过滤器?过滤器的原理?
  • 什么是Filter过滤器
  • 过滤器的作用
  • 过滤器有哪些作用?
  • 过滤器一:过滤器简介;创建第一个Filter;
  • 散热片选择注意事项
  • 分析MOS管发热严重的具体因素
  • mos管散热,功率,电流参数关联
  • rostopic中遇到Cannot load message
  • 用模板创建Maven显示No archetype found in remote catalog. Defaulting to internal catalog
  • 新建maven项目时,Run中报警告:No archetype found in remote catalog. Defaulting to internal catalo在远程目录中没有找到原型。
  • Spark运行程序异常信息: org.apache.spark.SparkException: Task not serializable 解决办法
  • Table options do not contain an option key ‘connector‘ for discovering a connector.
  • maven添加archetype-catalog
  • 警告:No archetype found in remote catalog. Defaulting to internal catalo在远程目录中没有找到原型。默认为内部编录
  • 在新建maven时候遇到错误: No archetype found in remote catalog. Defaulting to internal catalo
  • 解决maven创建中的警告:No archetype found in remote catalog. Defaulting to internal catalog.问题
  • [Maven]archetypeCatalog笔记
  • Spark源码之-CDH6下Spark2.4写Hive分区表异常
  • flink1.12.7+hudi 问题总结
  • Entity Framework链接数据库设置
  • 【万字详解】SQL 优化引擎内幕
  • datatable java实现_如何用Java实现.NET中DataTable功能
  • No archetype found in remote catalog. Defaulting to internal catalog 原因 与 解决
  • ASP.Net数据库配置
  • 急 小白 API返回的xml数据 遍历之后保存在数据库 本地的可以 但是要求保存在服务器的数据库里面 Data Source=10.28.1.xxx;Initial Catalo 报错说sa登录失败
  • pg数据库表存放在哪里_超详细的PG数据存储结构--逻辑结构和物理存储总结,值得收藏...
  • magento模板文件结构
  • 什么是硬分叉和软分叉?Tokenview

布隆过滤器和布谷鸟过滤器相关推荐

  1. 过滤请求绝技,布隆过滤器与布谷鸟过滤器

    欢迎关注方志朋的博客,回复"666"获面试宝典 大家都知道,在计算机中,IO一直是一个瓶颈,很多框架以及技术甚至硬件都是为了降低IO操作而生,今天聊一聊过滤器,先说一个场景: 我们 ...

  2. Redis 之布隆过滤器与布谷鸟过滤器

    欢迎关注方志朋的博客,回复"666"获面试宝典 大家都知道,在计算机中,IO一直是一个瓶颈,很多框架以及技术甚至硬件都是为了降低IO操作而生,今天聊一聊过滤器,先说一个场景: 我们 ...

  3. Redis 过滤请求绝技 — 布隆过滤器与布谷鸟过滤器

    来源:www.cnblogs.com/Courage129/p/14337466.html 大家都知道,在计算机中,IO一直是一个瓶颈,很多框架以及技术甚至硬件都是为了降低IO操作而生,今天聊一聊过滤 ...

  4. 过滤请求绝技 — 布隆过滤器与布谷鸟过滤器

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"书",获取 后台回复"k8s",可领取k8s资料 大家都知道,在计 ...

  5. 布隆过滤器与布谷鸟过滤器

    大家都知道,在计算机中,IO一直是一个瓶颈,很多框架以及技术甚至硬件都是为了降低IO操作而生,今天聊一聊过滤器,先说一个场景: 我们业务后端涉及数据库,当请求消息查询某些信息时,可能先检查缓存中是否有 ...

  6. Redis中的布隆过滤器与布谷鸟过滤器,你了解多少?

    点击关注公众号,实用技术文章及时了解 大家都知道,在计算机中,IO一直是一个瓶颈,很多框架以及技术甚至硬件都是为了降低IO操作而生,今天聊一聊过滤器,先说一个场景: 我们业务后端涉及数据库,当请求消息 ...

  7. Redis布隆过滤器与布谷鸟过滤器

    -     目录    - 大家都知道,在计算机中,IO一直是一个瓶颈,很多框架以及技术甚至硬件都是为了降低IO操作而生,今天聊一聊过滤器,先说一个场景: 我们业务后端涉及数据库,当请求消息查询某些信 ...

  8. RedisBloom 插件布隆过滤器,布谷鸟过滤器,Count-Min Sketch,TOPK使用详解

    文章目录 前言 一.如何安装 二.布隆过滤器 1. 使用介绍 2. 命令详解 三.布谷鸟过滤器 1. 使用介绍 2. 命令详解 三.Count-Min Sketch 1. 使用介绍 2. 命令详解 四 ...

  9. 过滤请求绝技 !布隆过滤器与布谷鸟过滤器

    点击上方"码农突围",马上关注 这里是码农充电第一站,回复"666",获取一份专属大礼包 真爱,请设置"星标"或点个"在看&quo ...

  10. Redis之布隆过滤器与布谷鸟过滤器

    点击上方"Java基基",选择"设为星标" 做积极的人,而不是积极废人! 每天 14:00 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java ...

最新文章

  1. ASP.NET的用户控件
  2. python教程:super()的用法
  3. day-17 包与模块
  4. 如何在不丢失文件的情况下快速重置Win11
  5. Rabbitmq消息中间件整合Springboot
  6. 【TensorFlow】MNIST手写数字识别
  7. 我用Python爬取1000封情书助力室友表白班花,却反转再反转...原来这就是班花的终极秘密!
  8. 实测解决:Initialization failed for ‘httpsstart.spring.io‘ Please check URL, network and proxy settings
  9. 新随笔 注:关注后可阅读(持续更新--------)
  10. 报时功能_拥有自鸣等20种复杂功能的百达翡丽6300G 连日期都可以用打簧报时听出来...
  11. centos 下安装nginx
  12. CSDN、sina博客在Zoundry中登记的API URL 收藏
  13. Nvidia驱动负优化与GTX1070的测试
  14. python输出空心等腰三角形_python学习,打印等腰直角三角形 实心正方形空心正方形...
  15. 启用tls的情况下openvpn配置文件合并到ovpn文件
  16. python3实现PAT乙级算法题库全集
  17. 用python(numpy)复现matlab代码
  18. 玩游戏4g计算机的内存不足,别再说内存不足了!教你一招彻底解决,电脑运行加速3倍!...
  19. 2018秋c语言程序设计考试答案,2018年自学考试《C语言程序设计》模拟试题【四篇】...
  20. D-OJ刷题日记:使用邻接矩阵实现最小生成树Prim算法 题目编号:1135

热门文章

  1. linux程序设计教程期末考试,LINUX程序设计期末大作业
  2. 如果你到了20岁,还没到 25岁
  3. 【eNSP】vlan隔离
  4. RPM包制作(三)构建rpm包的示例-来自红帽原厂课件
  5. uniapp、vue实现时间轴和刻度尺显示相关行程
  6. matlab repmat函数的用法
  7. WRF系列教程3:嵌套方式总结
  8. 张瀚荣:如何用UE4制作3D动作游戏
  9. 2019年,离开京东后的跳槽之旅(历史回顾和感悟)
  10. 这样解决“网易云音乐,播放失败请切换输出设备”,电脑没声音了等疑难杂症,win10系统,笔记本电脑声音问题