- 简述:
布隆过滤器是一种利用对象表示,通过插入自定义缓存判断对象是否存在、不存在的技术;
- 举例,已Guava工具包中的布隆为例
<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId></dependency>
在Guava工具包中实现的布隆过滤器,利用
hash
处理对象得出对应的hashcode
,将hashcode
存入一个
long
当中;Guava
工具包中的布隆过滤器没有扩容、删除处理,推荐创建时选择大于当前对象集2倍以上容量;
当新对象通过
hash
算出新的值后,与当前的Long
进行位与操作,如果位置已经是1
经过与操作不变,0
转变为1
如果存在0
转变为1
,表明这个对象是一个新的对象,没有被缓存过(即之前不存在的对象)
- 缺点
- 经过上述简介,我们知道
guava
实现的布隆过滤器存放在一个long
下,现在假使这个缓存不会扩容的情况下,当存入的对象越来越多后,long
的所有位都会变为1
,此时过滤器完全失去作用,会判断所有对象存在;- 假使两个对象存入
long
后刚好占据后4位,将后4位转变为1
,这时一个新对象经过hash
后需要转变long
的后4位为1
,这时同样会判为已存在,即1+3 = 4
,所以布隆过滤器判断已存在的对象不可信,即不存在的一定不存在,存在的不一定存在
;- 扩容问题,当过滤器中位为
1
的位越来越多后,布隆过滤器得出的结果就越会失真,使用扩容增加0
位可以提高准确率,但是使用扩容方案,扩容前的对象由于存在多个对象混合插入的情况(即同一个1
会代表多个对象),扩容后的缓存如何恢复扩容前缓存的记录。可以采取废弃旧布隆直接创建新布隆处理(需要缓存的对象是被持久化的),提高可用性的话可以考虑多个过滤器混合构成,当前一个不够用直接创建一个新的,拿前一个+后一个得出的结果作为最终结果- 删除问题,类似扩容即同一个
1
会代表多个对象,经过hash
后无法准确的只删除当前对象的1
,可以使1
增加计数器处理,当删除操作发生时,如果计数器存在值,优先减去计数器的值;
- 源码阅读
//先空着