布隆过滤器

目录

前言:

使用场景:

实现原理:

使用方式:

总结:

参考文章

高频面试考点:解读布隆过滤-极客时间


前言:

        提到布隆过滤器,我想大家首先能想到的就是解决缓存击穿的问题。确实不错,它确实能在Redis中应用的最为广泛。其实布隆过滤器是一种算法思想,常用来用作判断某一个对象是否存在。接下来我将从使用场景、实现原理、如何使用、优劣势来介绍它。


使用场景:

   在前言中我们提到了布隆过滤器常用来判断某一个对象是否存在,最常见的应用就是在Redis中,判断某一个key是否在Redis中存在,避免因为缓存穿透,认为恶意的攻击Redis缓存中不存在的值,直接将请求打到数据库,增加数据库的压力。

我们还有一些常用的使用场景比如:

  •    爬虫应用中,对重复爬虫的URL进行去重。
  •    垃圾邮件、短信过滤:通过判断当前的号码是否在维护的黑名单的号码池中,进行过滤,拦截。
  •    秒杀系统:查看用户是否重复购买。

实现原理:

    我们在前面提供布隆过滤器的主要使用场景,在于过滤,在于判断某个对象是否存在。如果说仅仅只是判断是否存在。

     其实我们可以使用HashMap去判断一个key是否存在。并且时间复杂度为O(1) , 可以说是非常的高效。在数据量小的情况下HashMap确实能帮助我们实现,但是当数据量特别大的时候,时间复杂度还是没有变化,但是空间复杂度却发生变化。HashMap需要更多的内存去存储数据的内容。

     为了解决内存占用的问题。布隆过滤器使用bit位的0和1来存储对象是否存在的结果。和HashMap一样,布隆过滤器也使用hash函数来判断对象是否存在,但是Hash函数我们知道有冲突的可能性。为了解决这个问题的解决方案是。如果一个Hash函数有冲突,那么就利用多个hash函数,然后将多个hash函数的判断结果存放到bit位中。这样既解决了内存消耗的问题,也解决了hash冲突的问题。具体实现原理如下图:


使用方式:

   在使用方式上,有分单机版和分布式版本。

在单机版本上,我们可以直接使用Google开源的Guava库布隆过滤器的实现类Bloomfilter

// 创建布隆过滤器对象

BloomFilter<Integer> filter = BloomFilter.create(

    Funnels.stringFunnel(Charsets.UTF_8),

    10000,

    0.1);

// 判断指定元素是否存在

System.out.println(filter.mightContain("ABC"));

// 将元素添加进布隆过滤器

filter.put("ABC");

System.out.println(filter.mightContain("ABC"));

            如果需要在分布式的场景下使用布隆过滤器就需要使用Redis,布隆过滤器是redis的一个插件,如果想使用需要单独安装。RedisBloom 是 Redis 官方推荐的布隆过滤器插件,可以通过https://github.com/RedisBloom/RedisBloom来下载。

 下面我们介绍一个判断元素是否存在的命令 

 bf.exists test user1

   bf.exists 判断 user1 是否在 test 过滤器中,与之对应的有一个 bf.mexists 命令可以批量判断多个元素是否存在:

bf.mexists test user1 user2

 最后我们介绍最重要的命令 bf.reserve,它的功能是创建一个布隆过滤器,

格式如下:

bf.reserve {key} {error_rate} {size} [expansin]

下面我介绍一下每个参数的含义:

  • key:布隆过滤器的名称。
  • error_rate : 误报率,这是一个小数。例如,error_rate 则配置为 0.01 表示误报率为 1%。该数字越小,服务器资源消耗就越大。考虑到资源占用,通常我们不会把这个指标设置得太小,可以把 error_rate 设置的稍大一些,因为我们使用布隆过滤器就是来判断某个元素不存在的,而判断某个元素存在的业务场景非常少。
  • size: 过滤器的容量。建议根据业务场景来配置,若空间不足会增加误判的几率。
  • expansion:作为最后一个参数,这个参数不是必须的,默认是 2。当布隆过滤器满了之后,布隆过滤器会自动创建默认容量是自己 2 倍的新的过滤器

总结:

 针对布隆过滤器使用的优势与劣势。

          首先最大的优势是在数据量特别大的场景。能占用比较小的场景下快速判断对象是否存在。虽然需要用多个hash函数,但是判断过程是CPU密集型的计算,相比HashMap的一次hash函数,但是需要在内存中比较是否对象是否相等。这是属于内存密集型计算,理论上布隆过滤器的判断更加高效。

          缺点就是:布隆过滤器存在一定的误判率,一般用于判断元素不存在。

经过它计算的结果是不存在,那么元素一定不存在,如果计算的结果为存在,会存在,不能一定确认元素存在,因为,可能所有的hash函数都冲突了,别的元素提前将bit为设置为1

参考文章

高频面试考点:解读布隆过滤-极客时间

算法(3)---布隆过滤器原理 - 雨点的名字 - 博客园

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值