前言:每个人总是对bloom过滤器赞不绝口。但它们到底是什么,又有什么用呢?本文将带你快速了解布隆过滤器的核心思想,并通过Bloom Filter 模拟器带你快速弄懂这大名鼎鼎的布隆过滤器。
操作
基本的bloom过滤器支持两种操作:检测和添加。
检测用于检查给定元素是否在集合中。他只有两个返回结果:
如果为false,那么元素肯定不在集合中。
如果为真,则该元素可能在集合中,存在误判的情况。误判率与bloom过滤器的大小、使用的哈希函数的数量和独立性有关。
添加只是在集合中添加一个元素。删除是不允许的,没有错误的否定,但有些扩展布隆过滤器可以允许删除已有元素,例如计数过滤器。
应用场景
经典案例是使用布隆过滤器减少对不存在的资源或不被允许的请求进行耗费性能的网络查找。防止用户更改产品id进行重新请求而导致的缓存击穿。场景:白名单,文章id,商品id等等。
如果元素不在布隆过滤器中,那么我们就可以确定不需要执行耗费性能的网络查找。另一方面,如果它在bloom过滤器中,我们执行查找。从总体来看,假如我们设定的误判率是1%,那么原本100个不需要进行查找的资源我们只进行了1次查询,服务器资源得到了大大的提升。
Bloomfilter.js
笔者在网上找到了一个通过JavaScript实现的Bloom Filter 模拟器,叫做bloomfilter.js。它使用非加密的Fowler-Noll-Vo哈希函数来提高速度。我们可以使用非加密的哈希函数,因为我们只关心哈希的均匀分布。
如果可能的话,该实现还使用JavaScript类型的数组,因为这些数组在执行低级的按位操作时速度更快。
演示
下面你会看到一个交互式的可视化的bloom过滤器,由bloomfilter.js提供。
Bloom Filter模拟器
在我增加了1-9这9个数字之后,布隆过滤器如下图所示:
这个时候我对10进行验证:
很显然,10不存在布隆过滤器的范畴之内,直接返回flase,我们可以直接对这个请求拒绝处理。
当我输入100000000时,布隆过滤器误判了,他提示这个数字可能存在:
原理
bloom filter本质上由一个长度为m的比特向量组成,由中心列表示。为了向bloom过滤器添加一个元素,我们将它提供给k个不同的哈希函数,并在产生的位置设置0和1,0代表这个位置不存在,1代表存在。在这个例子中,我设数组m为50 ,哈希算法个数k为3。注意,有时哈希函数会产生重叠的位置,所以可能会设置小于k个位置。
为了测试一个条目是否在过滤器中,我们再次将它提供给k个哈希函数。这一次,我们检查这些位置上是否有位没有被设置,如果有位没有设置,说明这个项肯定不在这个集合中,否则,它可能在这个集合中。
在我们实际使用情况中可以对误判率进行设置,一般情况下千分之三就够了。默认情况下使用三种hash算法,当我们设置的误判率越低,bloom过滤器的数组大小就越大,hash算法的个数就越多,性能就会很差。所以误判率设置为你能接受的范围内就可以了。
关注微信公众号:关于java,回复 布隆过滤器源码 获取源码。