【实战问题】-- 布隆过滤器的三种实践:手写,Redission以及Guava(2)
前面我们已经讲过布隆过滤器的原理【实战问题】-- 缓存穿透之布隆过滤器(1),都理解是这么运行的,那么一般我们使用布隆过滤器,是怎么去使用呢?如果自己去实现,又是怎么实现呢?
布隆过滤器
再念一次定义:
布隆过滤器(Bloom Filter
)是由布隆(Burton Howard Bloom
)在 1970 年提出的,它实际上是由一个很长的二进制向量和一系列随机hash
映射函数组成(说白了,就是用二进制数组存储数据的特征)。
譬如下面例子:有三个hash
函数,那么“陈六”就会被三个hash
函数分别hash
,并且对位数组的长度,进行取余,分别hash到三个位置。
如果对原理还有不理解的地方,可以查看我的上一篇文章。
手写布隆过滤器
那么我们手写布隆过滤器的时候,首先需要一个位数组,在Java
里面有一个封装好的位数组,BitSet
。
简单介绍一下BitSet
,也就是位图,里面实现了使用紧凑的存储空间来表示大空间的位数据。使用的时候,我们可以直接指定大小,也就是相当于创建出指定大小的位数组。
同时,BitSet
提供了大量的API
,基本的操作主要包括:
- 清空位数组的数据
- 翻转某一位的数据
- 设置某一位的数据
- 获取某一位的数据
- 获取当前的
bitSet
的位数
下面就讲一下,写一个简单的布隆过滤器需要考虑的点:
- 位数组的大小空间,需要指定,其他相同的时候,位数组的大小越大,
hash
冲突的可能性越小。 - 多个
hash
函数,我们需要使用hash
数组来存,hash
函数需要如何设置呢?为了避免冲突,我们应该使用多个不同的质数来当种子。 - 方法:主要实现两个方法,一个往布隆过滤器里面添加元素,另一个是判断布隆过滤器是否包含某个元素。
下面是具体的实现,只是简单的模拟,不可用于生产环境,hash
函数较为简单,主要是使用hash
值得高低位进行异或,然后乘以种子,再对位数组大小进行取余数:
运行结果,符合预期:
但是上面的这种做法是不支持预期的误判率的,只是可以指定位数组的大小。
当然我们也可以提供数据量,以及期待的大致的误判率来初始化,大致的初始化代码如下:
Redis实现
平时我们可以选择使用Redis
的特性于布隆过滤器,为什么呢?因为Redis
里面有类似于BitSet
的指令,比如设置位数组的值:
上面的key
是键,offset
是偏移量,value
就是1
或者0
。比如下面的就是将key1 的第7位置为1。
而获取某一位的数值可以使用下面这个命令:
借助redis
这个功能我们可以实现优秀的布隆过滤器,但是实际上我们不需要自己去写了,Redisson
这个客户端已经有较好的实现。
下面就是用法:
使用maven
构建项目,首先需要导包到pom.xml
:
代码如下,我使用的docker
,启动的时候记得设置密码,运行的时候修改密码不起效果:
实现的代码如下,首先需要连接上redis
,然后创建redission
,使用redission
创建布隆过滤器,直接使用即可。(可以指定预计的数量以及期待的误判率)
运行结果如下:值得注意的是,这是单台redis
的情况,如果是redis
集群的做法略有不同。
Google GUAVA实现
Google
提供的guava
包里面也提供了布隆过滤器,引入pom
文件:
具体的实现调用的代码如下,同样可以指定具体的存储数量以及预计的误判率:
上面三种分别是手写,redis
,guava
实践了布隆过滤器,只是简单的用法,其实redis
和guava
里面的实现也可以看看,有兴趣可以了解一下,我先立一个Flag
。
关于作者
秦怀,公众号【秦怀杂货店】作者,技术之路不在一时,山高水长,纵使缓慢,驰而不息。个人写作方向:Java源码解析,JDBC,Mybatis,Spring,redis,分布式,剑指Offer,LeetCode等,认真写好每一篇文章,不喜欢标题党,不喜欢花里胡哨,大多写系列文章,不能保证我写的都完全正确,但是我保证所写的均经过实践或者查找资料。遗漏或者错误之处,还望指正。
__EOF__

本文链接:https://www.cnblogs.com/Damaer/p/14764938.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库