说说布隆过滤器

791 阅读3分钟

前言

最近项目中遇到的一个问题, 顺便记录一下, 我们都知道布隆过滤器的使用场景,估计面试的时候也都问烂了,比如说会员营销秒杀场景,我们可以用布隆过滤器,去做一部分拦截的功能,防止缓存穿透.
这些场景布隆过滤器的数据很少变更或者没有明显的过期特性, 假如数据数据量非常大,过期的数据也很大, 随着时间的推移数据量越来越来可能一年有百亿级别的数据量,全部放在布隆过滤器里面服务器也是很难承受的, 下面还是从原理开始分析.

定义

布隆过滤器(英语:Bloom Filter)是 1970 年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。

原理

BloomFilter 是由一个固定大小的二进制向量或者位图(bitmap)和一系列映射函数组成的。

在初始状态时,对于长度为 m 的位数组,它的所有位都被置为0,如下图所示:

image.png

当有变量被加入集合时,通过 K 个映射函数将这个变量映射成位图中的 K 个点,把它们置为 1(假定有两个变量都通过 3 个映射函数) 比如说值 “baidu” 和三个不同的哈希函数分别生成了哈希值 1、4、7,值 “tencent”,如果哈希函数返回 4、9、13 的话则如下图

image.png

查询某个变量的时候我们只要看看这些点是不是都是 1 就可以大概率知道集合中有没有它了

  • 如果这些点有任何一个 0,则被查询变量一定不在;
  • 如果都是 1,则被查询变量很可能存在

为什么说是可能存在,而不是一定存在呢?那是因为映射函数本身就是散列函数,散列函数是会有碰撞的。

至于数学公式推导出来的误判率我这里就不阐述了.

误判率

布隆过滤器的误判是指多个输入经过哈希之后在相同的bit位置1了,这样就无法判断究竟是哪个输入产生的,因此误判的根源在于相同的 bit 位被多次映射且置 1。

特性

布隆过滤器的优缺点还是很明显的

  1. 一个元素判断为存在的时候,存在误判,不一定存在. 但是判断一个元素不存在那么他一定不存在.
  2. 布隆过滤器只能添加元素,不能删除元素.

使用

使用我这里也不做描述了,一般本地的话可以用Guava封装的布隆过滤器,分布式Redis布隆过滤器可以用Redisson封装的.

<dependencies>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>26.0-jre</version>
    </dependency>
</dependencies>

image.png

容量大小预估

参考下面两篇博客吧,我这边直接贴下结论,下面文章有的也有点出入,大概是100亿个URL, 失误率0.01%, 大概的大小是在25G左右

image.png

最后

为什么没有布隆过滤器删除元素呢, 因为删除元素可能导致更大的误判率.
我们有些场景需要定时的过期已经失效的数据,不需要放在布隆过滤器里面如何去做呢? 今天晚上和同事讨论的场景就是这个,可以从业务上面去做一些规避, 比如你1个月数据量是1亿,但是这些数据3个月之后就过期了,那么我们是不是可以每个月去建一个布隆过滤器,三个月之后定时任务去做删除.

还是那句话, 脱离了具体业务场景的架构都是空谈, 优秀的架构师都是"善假于物也!!!"

参考文档

www.cnblogs.com/qdhxhz/p/11…
www.cnblogs.com/D-Rui/artic…
blog.csdn.net/BrHiker/art…