布隆过滤器

什么是布隆过滤器

本质上布隆过滤器是一种数据结构,比较巧妙的概率型数据结构,特点是高效地插入和查询。根据查询结果可以用来告诉你 某样东西一定不存在或者可能存在 这句话是该算法的核心。
相比于传统的 List、Set、Map 等数据结构,它更高效、占用空间更少,但是缺点是其返回的结果是概率性的,而不是确切的,同时布隆过滤器还有一个缺陷就是数据只能插入不能删除
目前布隆过滤器已经有相应实现的开源类库啦,如Google的Guava类库,Twitter的 Algebird 类库,信手拈来即可,或者基于Redis自带的Bitmaps自行实现设计也是可以的。

使用场景

网页爬虫对URL的去重,避免爬去相同的URL地址。
垃圾邮件过滤,从数十亿个垃圾邮件列表中判断某邮箱是否是杀垃圾邮箱。
解决数据库缓存击穿,黑客攻击服务器时,会构建大量不存在于缓存中的key向服务器发起请求,在数据量足够大的时候,频繁的数据库查询会导致挂机。
秒杀系统,查看用户是否重复购买。
适用场景:

  1. 缓存系统: 用于快速判断某个对象是否在缓存中,可以减少缓存穿透带来的数据库压力。
  2. 防止重复请求: 用于过滤掉已经处理过的请求,避免重复执行相同的操作。
  3. 黑名单过滤: 用于过滤恶意IP地址、URL等,提高系统的安全性。
  4. 网页爬虫: 用于判断某个URL是否已经被爬取过,避免重复爬取相同的页面。
  5. 数据同步过滤: 用于判断某个数据是否已经同步到目标系统,避免重复同步。
    总的来说,布隆过滤器适用于对查询速度要求较高,可以容忍一定误判率的场景,但不适用于需要精确匹配和支持删除操作的场景。

数据如何存入布隆过滤器

布隆过滤器是由一个很长的bit数组和一系列哈希函数组成的。
数组的每个元素都只占1bit空间,并且每个元素只能为0或1。
布隆过滤器还拥有k个哈希函数,当一个元素加入布隆过滤器时,会使用k个哈希函数对其进行k次计算,得到k个哈希值,并且根据得到的哈希值,在维数组中把对应下标的值置位1。
判断某个数是否在布隆过滤器中,就对该元素进行k次哈希计算,得到的值在位数组中判断每个元素是否都为1,如果每个元素都为1,就说明这个值在布隆过滤器中。

布隆过滤器的原理

布隆过滤器原理:它由初始值为 0的位图数组和 N 个哈希函数组成。一个对一个 key 进行N 个 hash 算法获取 N 个值,在比特数组中将这 N 个值散列后设定为 1,然后查的时候如果特定的这几个位置都为 1,那么布隆过滤器判断该key 存在。
布隆过滤器的原理相对简单,主要基于位数组(或称为位图)和一系列哈希函数。下面是它的基本原理:
位数组(Bit Array): 布隆过滤器使用一个由多个二进制位组成的位数组,初始时所有位都被设置为0。
哈希函数(Hash Functions): 布隆过滤器需要选择并设置多个独立的哈希函数,这些哈希函数可以将任意输入映射到位数组中的不同位置。
添加元素(Addition): 当要向布隆过滤器中添加一个元素时,这个元素会经过多个哈希函数的处理,每个哈希函数会将元素映射到位数组的不同位置,并将这些位置的对应位设置为1。
查询元素(Query): 当要查询一个元素是否存在于布隆过滤器中时,同样将这个元素经过多个哈希函数的处理,然后检查对应位置的位是否都为1。如果有任何一个位置的位为0,则可以确定该元素一定不在布隆过滤器中;如果所有位置的位都为1,则可能存在于布隆过滤器中,但也可能是误判。
误判率(False Positive): 布隆过滤器的误判率主要与哈希函数的数量、位数组的大小以及插入元素的数量有关。误判率会随着插入的元素数量增加而增加,但可以通过增加位数组的大小和哈希函数的数量来降低误判率。
总的来说,布隆过滤器利用位数组和多个哈希函数的特性,可以高效地判断一个元素是否属于一个集合,并且具有快速查询的特点,但也可能会出现误判的情况。
bloomfilter就类似于一个hash set,用于快速判某个元素是否存在于集合中,其典型的应用场景就是快速判断一个key是否存在于某容器,不存在就直接返回。布隆过滤器的关键就在于hash算法和容器大小,下面先来简单的实现下看看效果,我这里用guava实现的布隆过滤器:

必须首先把DB的数据同步给布隆过滤器
能判断一定不存在,但是不能判断一定存在(hash冲突)

布隆过滤器优缺点

布隆过滤器(Bloom Filter)是一种基于概率的数据结构,用于判断一个元素是否存在于一个集合中。
布隆过滤器是一种用于判断一个元素是否属于一个集合的数据结构,它具有以下优点和缺点,以及适用场景:
优点:

  1. 高效的查询性能: 布隆过滤器查询的时间复杂度是O(1),与集合中的元素数量无关,因此查询速度非常快。
  2. 节省空间: 布隆过滤器使用的是位数组和一系列哈希函数,相比于直接存储所有元素的集合,它可以节省大量的空间。
  3. 可扩展性: 布隆过滤器可以根据需要动态扩展大小,而且在不需要删除元素的情况下,可以一直使用而不会发生碰撞。
  4. 空间效率:布隆过滤器在空间使用上非常高效,其存储空间和插入/查询时间都是常数,与集合中元素的数量无关。因此,当需要处理大规模数据时,布隆过滤器可以显著减少存储空间的使用。
  5. 时间效率:布隆过滤器的查询速度非常快,时间复杂度为O(K),其中K为哈希函数的个数,通常较小。这使得布隆过滤器在处理大量数据时具有很高的性能。
  6. 并行计算:布隆过滤器中的哈希函数相互独立,没有关联,这使得它可以方便地利用硬件进行并行计算,进一步提高性能。
  7. 保密性:布隆过滤器不需要存储元素本身,只存储元素的哈希值,因此在某些对保密要求较高的场合具有优势。
  8. 全集表示:当数据量很大时,布隆过滤器可以表示全集,而其他数据结构可能无法做到。
    缺点:
  9. 存在误判: 布隆过滤器可能会出现误判,即判断一个元素属于集合但实际上并不属于。这是由于哈希函数的冲突造成的,因为多个不同的元素可能被映射到同一个位上。
    误判率:布隆过滤器是一种基于概率的数据结构,存在一定的误判率。即,当查询一个元素时,即使该元素并不存在于集合中,布隆过滤器也可能错误地认为它存在。这可能会导致一些不必要的误报或误操作。为了降低误判率,可以增加哈希函数的个数或使用更长的位数组,但这也会增加存储空间和计算成本。
  10. 无法删除元素: 布隆过滤器一般不能直接删除元素,因为删除元素会影响到其他元素的判断结果。
    删除困难:布隆过滤器不支持直接删除元素。因为布隆过滤器的位数组被多个元素共享,删除某个元素可能会影响其他元素的判断结果。虽然有一些变种布隆过滤器支持删除操作,但它们通常具有更高的误判率或更复杂的实现方式。
  11. 不支持元素的部分匹配: 布隆过滤器只能判断一个元素是否属于集合,不能提供具体的匹配信息,例如无法返回与某个查询元素相似的元素。
    不能获取元素本身:布隆过滤器只能判断元素是否存在于集合中,但不能获取元素本身的值。如果需要获取元素的值,则需要使用其他数据结构(如哈希表)来存储元素及其对应的值。
  12. 计数回绕问题:在采用计数方式删除元素时,如果计数器回绕(即超过最大值后回到0),可能会导致误判或删除错误。因此,在使用计数方式删除元素时需要特别小心。
    总的来说,布隆过滤器在处理大规模数据时具有很高的性能优势,但也需要根据具体应用场景来权衡其优缺点。

布隆过滤器为什么会有误判

当插入的元素越来越多时,当一个不在布隆过滤器中的元素,经过同样规则的哈希计算之后,得到的值在位数组中查询,有可能这些位置因为其他的元素先被置1了。
所以布隆过滤器存在误判的情况,但是如果布隆过滤器判断某个元素不在布隆过滤器中,那么这个值就一定不在。

布隆过滤器怎么减少误判和怎么去减少hash冲突

1.增加hash次数
2.增大位图大小
减少布隆过滤器的误判率可以通过以下方法来实现:

  1. 增加位数组的大小(Increase Size of Bit Array): 增加位数组的大小可以减少哈希碰撞的概率,从而减少误判率。更大的位数组意味着可以使用更多的位来表示元素的存在情况,使得误判的可能性降低。
  2. 增加哈希函数的数量(Increase Number of Hash Functions): 使用更多的哈希函数可以增加元素在位数组中的散列分布,从而减少冲突的可能性。每个额外的哈希函数可以提供更多的独立位来表示元素的存在情况,进一步降低误判率。
  3. 选择合适的哈希函数(Choose Suitable Hash Functions): 选择良好的哈希函数也可以减少冲突的可能性。理想的哈希函数应该具有良好的散列性质,能够将元素均匀地映射到位数组的不同位置,避免出现集中在某些位置的情况。
  4. 控制插入元素的数量(Control Number of Inserted Elements): 控制插入元素的数量可以限制位数组中被设置为1的位的数量,从而降低误判率。当位数组中被设置为1的位过多时,误判的可能性会增加,因此在允许的范围内控制插入元素的数量可以有效减少误判率。
  5. 结合其他数据结构(Combine with Other Data Structures): 在布隆过滤器的基础上,可以结合其他数据结构来进一步减少误判率。例如,可以使用一个小型的真实集合来存储布隆过滤器认为存在的元素,然后在查询时先检查布隆过滤器,再在真实集合中进行确认,以降低误判率。
    综上所述,通过合理调整布隆过滤器的参数、选择适当的哈希函数以及结合其他数据结构,可以有效地减少误判率,提高布隆过滤器的准确性。
  • 26
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

思静语

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值