当前位置:   article > 正文

布隆(Bloom Filter)过滤器——全面讲解,建议收藏_布隆过滤器

布隆过滤器

3.5 修改元素

3.6 删除元素

4、Redis集成布隆过滤器

4.1 版本要求

4.2 安装&编译

4.3 Redis集成

5、Redis中布隆过滤器指令使用

5.1 bf.add

5.2 bf.madd

5.3 bf.exists

5.3 bf.mexists

6、Java本地内存使用布隆过滤器

6.1 引入pom依赖

6.2 编写测试代码

6.3 测试结果

6.4 参数说明

6.5 fpp&expectedInsertions

7、Java集成Redis使用布隆过滤器

7.1 引入pom依赖

7.2 编写测试代码

7.3 测试结果


1、什么是布隆过滤器


布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。

上面这句介绍比较全面的描述了什么是布隆过滤器,如果还是不太好理解的话,就可以把布隆过滤器理解为一个set集合,我们可以通过add往里面添加元素,通过contains来判断是否包含某个元素。由于本文讲述布隆过滤器时会结合Redis来讲解,因此类比为Redis中的Set数据结构会比较好理解,而且Redis中的布隆过滤器使用的指令与Set集合非常类似(后续会讲到)。

学习布隆过滤器之前有必要先聊下它的优缺点,因为好的东西我们才想要嘛!

布隆过滤器的优点:

  • 时间复杂度低,增加和查询元素的时间复杂为O(N),(N为哈希函数的个数,通常情况比较小)

  • 保密性强,布隆过滤器不存储元素本身

  • 存储空间小,如果允许存在一定的误判,布隆过滤器是非常节省空间的(相比其他数据结构如Set集合)

布隆过滤器的缺点:

  • 有点一定的误判率,但是可以通过调整参数来降低

  • 无法获取元素本身

  • 很难删除元素

2、布隆过滤器的使用场景


布隆过滤器可以告诉我们 “某样东西一定不存在或者可能存在”,也就是说布隆过滤器说这个数不存在则一定不存,布隆过滤器说这个数存在可能不存在(误判,后续会讲),**利用这个判断是否存在的特点可以做很多有趣的事情。

  • 解决Redis缓存穿透问题(面试重点)

  • 邮件过滤,使用布隆过滤器来做邮件黑名单过滤

  • 对爬虫网址进行过滤,爬过的不再爬

  • 解决新闻推荐过的不再推荐(类似抖音刷过的往下滑动不再刷到)

  • HBase\RocksDB\LevelDB等数据库内置布隆过滤器,用于判断数据是否存在,可以减少数据库的IO请求

3、布隆过滤器的原理


3.1 数据结构

布隆过滤器它实际上是一个很长的二进制向量和一系列随机映射函数。以Redis中的布隆过滤器实现为例,Redis中的布隆过滤器底层是一个大型位数组(二进制数组)+多个无偏hash函数。

一个大型位数组(二进制数组)

位数组.png

多个无偏hash函数:

无偏hash函数就是能把元素的hash值计算的比较均匀的hash函数,能使得计算后的元素下标比较均匀的映射到位数组中。

如下就是一个简单的布隆过滤器示意图,其中k1、k2代表增加的元素,a、b、c即为无偏hash函数,最下层则为二进制数组。

布隆过滤器.png

3.2 空间计算

在布隆过滤器增加元素之前,首先需要初始化布隆过滤器的空间,也就是上面说的二进制数组,除此之外还需要计算无偏hash函数的个数。布隆过滤器提供了两个参数,分别是预计加入元素的大小n,运行的错误率f。布隆过滤器中有算法根据这两个参数会计算出二进制数组的大小l,以及无偏hash函数的个数k。

它们之间的关系比较简单:

  • 错误率越低,位数组越长,控件占用较大

  • 错误率越低,无偏hash函数越多,计算耗时较长

如下地址是一个免费的在线布隆过滤器在线计算的网址:

https://krisives.github.io/bloom-calculator/

image.png

3.3 增加元素

往布隆过滤器增加元素,添加的key需要根据k个无偏hash函数计算得到多个hash值,然后对数组长度进行取模得到数组下标的位置,然后将对应数组下标的位置的值置为1

  • 通过k个无偏hash函数计算得到k个hash值

  • 依次取模数组长度,得到数组索引

  • 将计算得到的数组索引下标位置数据修改为1

例如,key = Liziba,无偏hash函数的个数k=3,分别为hash1、hash2、hash3。三个hash函数计算后得到三个数组下标值,并将其值修改为1.

如图所示:

增加元素.png

3.4 查询元素

布隆过滤器最大的用处就在于判断某样东西一定不存在或者可能存在,而这个就是查询元素的结果。其查询元素的过程如下:

  • 通过k个无偏hash函数计算得到k个hash值

  • 依次取模数组长度,得到数组索引

  • 判断索引处的值是否全部为1,如果全部为1则存在(这种存在可能是误判),如果存在一个0则必定不存在

关于误判,其实非常好理解,hash函数在怎么好,也无法完全避免hash冲突,也就是说可能会存在多个元素计算的hash值是相同的,那么它们取模数组长度后的到的数组索引也是相同的,这就是误判的原因。例如李子捌和李子柒的hash值取模后得到的数组索引都是1,但其实这里只有李子捌,如果此时判断李子柒在不在这里,误判就出现啦!因此布隆过滤器最大的缺点误判只要知道其判断元素是否存在的原理就很容易明白了!

3.5 修改元素

3.6 删除元素

布隆过滤器对元素的删除不太支持,目前有一些变形的特定布隆过滤器支持元素的删除!关于为什么对删除不太支持,其实也非常好理解,hash冲突必然存在,删除肯定是很苦难的!

4、Redis集成布隆过滤器


4.1 版本要求

  • 推荐版本6.x,最低4.x版本,可以通过如下命令查看版本:

redis-server -v

image.png

  • 插件安装,网上大部分推荐v1.1.1,文章写的时候v2.2.6已经是release版本了,用户自己选择,地址全在下面(2.2.6官网介绍说是1.0版本的维护版本,如果不想使用新的功能,无需升级!)

image.png

v1.1.1

https://github.com/RedisLabsModules/rebloom/archive/v1.1.1.tar.gz

v2.2.6

https://github.com/RedisLabsModules/rebloom/archive/v2.2.6.tar.gz

4.2 安装&编译

以下安装全部在指定目录下完成,可以选择一个合适的统一目录进行软件安装和管理。

4.2.1 下载插件压缩包

wget https://github.com/RedisLabsModules/rebloom/archive/v2.2.6.tar.gz

4.2.2 解压

tar -zxvf v2.2.6.tar.gz

4.2.3 编译插件

cd RedisBloom-2.2.6/

make

image.png

编译成功后看到redisbloom.so文件即可

4.3 Redis集成

4.3.1 Redis配置文件修改

  • redis.conf配置文件中加入如RedisBloom的redisbloom.so文件的地址

  • 如果是集群则每个配置文件中都需要加入redisbloom.so文件的地址

  • 添加完成后需要重启redis

loadmodule /usr/local/soft/RedisBloom-2.2.6/redisbloom.so

redis.conf配置文件中预置了loadmodule的配置项,我们可以直接在这里修改,后续修改会更加方便。

image.png

保存退出后一定要记得重启Redis!

保存退出后一定要记得重启Redis!

保存退出后一定要记得重启Redis!

4.3.2 测试是否成功

Redis集成布隆过滤器的主要指令如下:

  • bf.add 添加一个元素

  • bf.exists 判断一个元素是否存在

  • bf.madd 添加多个元素

  • bf.mexists 判断多个元素是否存在

连接客户端进行测试,如果指令有效则证明集成成功

image.png

如果出现如下情况(error) ERR unknown command ,可以通过如下方法检查:

  • SHUTDOWN Redis实例,再重启实例,再次测试

  • 检查配置文件是否配置redisbloom.so文件地址正确

  • 检查Redis的版本是否过低

image.png

5、Redis中布隆过滤器指令使用


5.1 bf.add

bf.add表示添加单个元素,添加成功返回1

127.0.0.1:6379> bf.add name liziba

(integer) 1

image.png

5.2 bf.madd

bf.madd表示添加多个元素

127.0.0.1:6379> bf.madd name liziqi lizijiu lizishi

1) (integer) 1

2) (integer) 1

3) (integer) 1

image.png

5.3 bf.exists

bf.exists表示判断元素是否存在,存在则返回1,不存在返回0

127.0.0.1:6379> bf.mexists name liziba

1) (integer) 1

image.png

5.3 bf.mexists

bf.mexists表示判断多个元素是否存在,存在的返回1,不存在的返回0

127.0.0.1:6379> bf.mexists name liziqi lizijiu liziliu

1) (integer) 1

2) (integer) 1

3) (integer) 0

image.png

6、Java本地内存使用布隆过滤器


使用布隆过滤器的方式有很多,还有很多大佬自己手写的,我这里使用的是谷歌guava包中实现的布隆过滤器,这种方式的布隆过滤器是在本地内存中实现。

6.1 引入pom依赖

com.google.guava

guava

29.0-jre

6.2 编写测试代码

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

尾声

评论里面有些同学有疑问关于如何学习material design控件,我的建议是去GitHub搜,有很多同行给的例子,这些栗子足够入门。

有朋友说要是动真格的话,需要NDK以及JVM等的知识,首现**NDK并不是神秘的东西,**你跟着官方的步骤走一遍就知道什么回事了,无非就是一些代码格式以及原生/JAVA内存交互,进阶一点的有原生/JAVA线程交互,线程交互确实有点蛋疼,但平常避免用就好了,再说对于初学者来说关心NDK干嘛,据鄙人以前的经历,只在音视频通信和一个嵌入式信号处理(离线)的两个项目中用过,嵌入式信号处理是JAVA->NDK->.SO->MATLAB这样调用的我原来MATLAB的代码,其他的大多就用在游戏上了吧,一般的互联网公司会有人给你公司的SO包的。
至于JVM,该掌握的那部分,相信我,你会掌握的,不该你掌握的,有那些专门研究JVM的人来做,不如省省心有空看看计算机系统,编译原理。

一句话,平常多写多练,这是最基本的程序员的素质,尽量挤时间,读理论基础书籍,JVM不是未来30年唯一的虚拟机,JAVA也不一定再风靡未来30年工业界,其他的系统和语言也会雨后春笋冒出来,但你理论扎实会让你很快理解学会一个语言或者框架,你平常写的多会让你很快熟练的将新学的东西应用到实际中。
初学者,一句话,多练。

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

terial design控件,我的建议是去GitHub搜,有很多同行给的例子,这些栗子足够入门。

有朋友说要是动真格的话,需要NDK以及JVM等的知识,首现**NDK并不是神秘的东西,**你跟着官方的步骤走一遍就知道什么回事了,无非就是一些代码格式以及原生/JAVA内存交互,进阶一点的有原生/JAVA线程交互,线程交互确实有点蛋疼,但平常避免用就好了,再说对于初学者来说关心NDK干嘛,据鄙人以前的经历,只在音视频通信和一个嵌入式信号处理(离线)的两个项目中用过,嵌入式信号处理是JAVA->NDK->.SO->MATLAB这样调用的我原来MATLAB的代码,其他的大多就用在游戏上了吧,一般的互联网公司会有人给你公司的SO包的。
至于JVM,该掌握的那部分,相信我,你会掌握的,不该你掌握的,有那些专门研究JVM的人来做,不如省省心有空看看计算机系统,编译原理。

一句话,平常多写多练,这是最基本的程序员的素质,尽量挤时间,读理论基础书籍,JVM不是未来30年唯一的虚拟机,JAVA也不一定再风靡未来30年工业界,其他的系统和语言也会雨后春笋冒出来,但你理论扎实会让你很快理解学会一个语言或者框架,你平常写的多会让你很快熟练的将新学的东西应用到实际中。
初学者,一句话,多练。

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/859291
推荐阅读
相关标签
  

闽ICP备14008679号