BloomFilter:布隆过滤器和Redis缓存穿透

本文介绍布隆过滤器的基本原理与特性,探讨其如何通过牺牲存储空间换取高效的查询速度,尤其适用于大数据环境中快速判断元素是否存在的情况。此外,还讨论了布隆过滤器在解决缓存穿透问题上的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概念

BloomFilter,中文名叫布隆过滤器,用于判断目标值是否存在。

例子

设一个队伍有10人。需要判断张三是否在其中。
常规的思路就是遍历这10人。然而随着人数规模的增加,遍历所需要的时间会越来越长。
因此考虑这样一个方案:维护一个辅助list,其元素值为0或1,表示该人是否在队伍中。索引使用每个人姓名的笔画数。例如张三,姓名笔画数是10画,那么list[10]就设为1。这样,当我们需要判断张三是否在队伍中时,先算出笔画数10,然后看list[10]是否为1。若list[10]为0,则说明张三一定不在队伍里,就不需要遍历队伍了。
然而这方案有个很明显的特点:list[10]为1,并不能说明张三一定在,因为有跟张三姓名笔画相同的人;但list[10]为0,说明张三一定不在。于是,当list[10]为1时,就去遍历一下队伍,看张三是否在。
这也意味着,如果张三要从队伍中去掉,则需要遍历整个队伍看是否还有其他人的姓名笔画也是10。当确定没有这样的人时,才能将list[10]由1改为0。
可以很明显地看出,相比于直接遍历的方案,该方案需要一个额外的辅助list空间。

原理

如上,就是BloomFilter的流程。
关于辅助list,BloomFilter定义了一个位列阵,其元素值是一个二进制,仅为0或1。默认为0。
BloomFilter是一个典型的用空间换时间的算法。

存储

关于辅助list空间的索引,为了尽可能减少冲突带来的影响,BloomFilter使用了三次hash。也就是一个数据,对其进行三次不同的hash,分别得到三个值k、l、m。然后使用这三个值作为位列阵的索引值,将对应元素值设为1。

查找

当需要判断某个数据是否存在时,对该数据进行三次hash,分别得到k、l、m。然后使用这三个值作为位列阵的索引值,查询对应的元素值。
若三个元素值都为1,则说明该元素可能是存在的;但若至少有一个元素值为0,则说明该元素一定是不存在的。
对于一个元素,若其三个位列阵的点位值都是1,但该元素实际却并不存在,则称之为误判。

删除

就像上述例子中说的,若要删除某个元素,则需对所有元素进行遍历才能确定位列阵中该元素对应的三个值是否可改为0。因此删除困难。一般来说,只添加,不删除。

特点

对于一个数据,若其通过了BloomFilter判定,则不一定在数据库中。但若未通过,则一定不在。
可以看出,BloomFilter有如下优点:

  • 插入/查询时间复杂度是O(1),非常快。
  • 并不存储数据本身,保密性好。
  • 可对所有数据实现映射。

对应地,BloomFilter有如下缺点:

  • 随着元素增多,误算率也会增加。
  • 只能添加元素,不能删除元素。

Redis中BloomFilter的应用

Redis对BloomFilter进行了应用。其实现方式有两种:使用Redis的bitmap实现;使用布隆过滤器插件实现。
根据原理可以知道,BloomFilter需要设置一个初始大小,用于表示预计放入的元素数量。可以想象,该值若过小,则hash冲突的元素就会增多,从而导致误判率的提升。因此该值应设置较大一些。

缓存穿透

对一个数据访问,先判断是否在Redis中,若是则返回;若否则查询数据库,并将查到的值设置到Redis中。这样下次查询就可以顺利查到了。
但若一个数据访问,既不在Redis中也不在数据库中,那么该访问将先访问Redis再访问数据库。若再次访问该数据,则该流程会再次重复。
于是,攻击黑客就发送大量针对不存在数据的请求,那么上述访问流程就会反复重复,导致数据库承担大量压力。在该流程中缓存这道墙形同虚设,称为缓存穿透。
BloomFilter就可以很好地解决该问题:一个针对虚假数据的访问,Redis借助BloomFilter可以很明确地判断出该数据一定不在数据库中,于是就直接返回,不再查询数据库。

缓存穿透和缓存击穿

注意区别二者的概念:

  • 缓存穿透:Redis和数据库中都没有目标数据,每次都要先查Redis再查数据库。
  • 缓存击穿:Redis和数据库中存在目标数据,但Redis的数据过期了。此时有大量并发请求访问该数据,导致这些请求全部发送到数据库上,为数据库带来巨大压力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值