布隆过滤器简介

0. 起因

以前写爬虫的时候用过布隆过滤器(Bloom filter)作为判断和去重,今天在看RPC代码的时候发现也有布隆过滤器的身影。因为之前了解过,看到名字的瞬间就明了作者想要做什么,虽然细节记不清了。因此在这里做个记录,后面如果需要扣细节,心里懂得了原理看起来也方便。

1. 什么是布隆过滤器?

布隆过滤器是由布隆(Burton Howard Bloom)在1970年提出的一个可以高效的判断出给定元素“肯定不存在”或者“可能已经存在”的概率型数据结构,这个高效不仅体现在时间上,也体现在内存上。
基本的布隆过滤器支持判断和添加这两个操作,但是不支持删除。但是经过扩展,布隆过滤器也可以实现删除,例如counting filter。
对于判断操作,如果返回假则可以说明给定元素肯定不存在;而如果返回真,则只能说给定元素有可能已经存在了。

2. 应用场景

布隆过滤器一般用于去除一些不必要的检索操作,特别是当这种检索相当耗时的时候。例如,有一个很长的链表,如果检索一个不存在的元素,常规操作需要遍历整个链表。虽然可以结合红黑树等数据结构减少减速的数量,但随着元素数量的增减,时间也会越来越长。但是如果使用了布隆过滤器,就可以在相对固定的时间内知道某个元素不存在,免去了多于的耗时。

3. 原理

布隆过滤器的基本思想是哈希函数,对于一个良好的哈希函数,任意两个不同的对象的哈希值基本是不一样。
其算法如下:

  1. 首先选取k个hash函数,n可以是除0外的任意正整数,每个函数可以把key散列成为1个整数;
  2. 开辟个数组空间,以比特位(bit)为单位,每个位都初始化为0;
  3. 某个元素加入集合时,用选取的k个hash函数计算分别计算出k个哈希值应该都小于数组长度;
  4. 判断某个key是否在集合时,查询第三部计算出的哈希值所对应的数组元素是否为1,如果存在至少一个哈希值对应的元素为0,则元素不存在;如果全部哈希值对应的元素都为1,则该元素可能已经存在;
  5. 添加某个元素的时候,只需要将哈希值对应的数组元素都设置为1即可。

例如下面这个例子:
在内存中开辟了一片连续的数组空间,并使用三个不同的哈希函数对元素进行哈希操作。如图1所以,当布隆过滤其中已经存在a, b, c, d, e, f,这几个元素的情况下,这时,需要判断元素1234567890qwer是否已经存在,三个哈希函数得到的哈希值指向的数组元素都已经被设置成1,虽然此时1234567890qwer肯定不存在,但是布隆过滤器返回的结果是元素已经存在,因此布隆过滤器存在一定误判的可能。
图一 1 布隆过滤器误判

图1 布隆过滤器误判

而图2中,对于n元素,三个哈希函数中只有一个哈希函数得出的结果指向的数组元素中为0,但这足以肯定的得出n不存在这个结论。
图2 布隆过滤器可以肯定元素不存在

图2 布隆过滤器可以肯定元素不存在

4. 哈希函数的数量和数组长度选择

既然是概率型数据结构,那么对于参数的选择肯定有一套对应的数学公式,布隆过滤器中涉及的哈希函数数量k,数组长度m,元素数量n以及误报率p的公式如图3所示,通过下面的公式,可以得到比较合理的参数:
图3 布隆过滤器公式

图3 布隆过滤器参数选择公式

至于公式怎么推导出来的,这里(wo)就(ye)不(bu)介(zhi)绍(dao)了。

公众号二维码

首发于个人微信公众号TensorBoy。微信扫描上方二维码或者微信搜索TensorBoy并关注,及时获取更多最新文章!
C++ | Python | Linux | 原理 | 源码,有一起玩耍的么?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redisson布隆过滤器是基于Redis实现的Java分布式布隆过滤器。它可以在多个JVM节点或其他进程中通过相同的KEY获取到布隆过滤器布隆过滤器的主要功能是判断某个元素是否存在于容器中,因此非常适合解决缓存穿透问题和检查数据是否重复的场景。使用Redisson布隆过滤器时,需要单独开一个定时任务来初始化布隆过滤器的数据,并在删除或更新数据时重新刷新布隆过滤器。虽然使用布隆过滤器可能稍显麻烦,但可以使用Redis的Set类型来替代。\[1\]\[2\] 在代码示例中,可以看到使用Redisson布隆过滤器的示例代码。首先通过redisson.getBloomFilter方法获取布隆过滤器实例,然后使用tryInit方法初始化布隆过滤器的容量和误差率。接下来可以使用add方法向布隆过滤器中添加元素,使用contains方法判断元素是否存在于布隆过滤器中。\[2\]\[3\] 总结来说,Redisson布隆过滤器是一种解决缓存穿透和检查数据重复的有效工具,但在使用时需要注意初始化和刷新布隆过滤器的操作。 #### 引用[.reference_title] - *1* *2* *3* [从头开始学Redisson--------布隆过滤器](https://blog.csdn.net/yanluandai1985/article/details/104848454)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值