Redis缓存穿透“新杀招“:布隆过滤器Bloom Filter

本文探讨了缓存穿透问题的一个补充解决方案——布隆过滤器。通过介绍布隆过滤器的工作原理和优势,阐述了如何利用它来防止恶意请求导致的数据库崩溃,并分析了其误判率和内存占用。同时,提出了优化布隆过滤器错误率的方法,以及在服务器层应用布隆过滤器以进一步优化资源利用。

场景分析

这篇文章来讲述缓存穿透的补充解决方案.
为什么要用补充来形容呢?

在之前的文章中,我们提到缓存穿透的解决方案时,我是这么说的:
关于缓存穿透,我们可以在用户访问数据库后将null值存入Redis来解决.

那么这样就真的万无一失了吗??

No No No!!!

当然不是.我们设想如下的场景:

某组织或某个人就是想干掉你的服务器,他写了一个这样的程序:

定义n=-1;
使用循环,每次循环n=n-1;
然后每次循环都去利用n作为商品id访问你的数据库.

他将这个程序放在了他所控制的许多个客户端中.

那么此时,发现问题了吗?小天才?

就算我们每次都把null值放入Redis,但是负数是没有极限的呀!

如果一直这么下去,数据库崩溃不是早晚的事情么?

而且,Redis自带一些数据的淘汰机制,会用新数据替换旧数据,那么这么多的负数数据存入到Redis,我们正常的数据也没有办法缓存了,一些正常的请求也去直接访问数据库了.那可怎么办?

有的读者可能会想到,我直接服务器写一段代码,把所有的负数id的请求打回去不就可以了吗?

是,针对我这个场景,你完全可以这么干.但是治标不治本呀,

如果我换一个场景,他不再使用负数,而是使用UUID来制作id,继续循环访问,你怎么办?

那再来换,他也不用UUID,他用一系列的自定义随机数函数生成来方法,怎么办?

难道我们要想到所有的场景,然后针对所有的场景进行逐一思考实施防御机制吗?

No No No!!!

用最简单的代码实现复杂的功能才是我们的追求!

所以,我们引入Bloom Filter 布隆过滤器.

布隆过滤器(Bloom Filter)

什么是布隆过滤器及作用?

布隆过滤器 是1970年由布隆提出的 可以理解为是一个数组和一堆哈希函数的结合体.
文邹邹一点的来说就是一个很长的二进制向量和一系列随机映射函数.
用来检索一个元素是否存在于集合中.

为什么使用布隆过滤器?

首先就是解决上边的场景.
再者就是它本身的查询速度和空间的利用就远超于一般的算法.

布隆过滤器的缺点

为了更高的效率,会有一定的错误率. 并且删除比较困难.

布隆过滤器的原理

在这里插入图片描述

布隆过滤器的原理,就是将数据库的数据全部利用哈希函数,计算出哈希值,然后将数组中以这个哈希值为下标的位置改为1,证明这个位置代表一个数字.
当有请求过来时,根据请求数据利用哈希函数计算出哈希值,查看数组中以这个函数为下标的位置是否为1,如果为1,则代表数据库中可能存在这个数据,如果为0.则代表这个数据库中不可能存在该数据.

把数据库所有数据存在布隆过滤器会不会占用特别多的内存而导致查询速度变慢呢?

不会的,因为原理中我们提到了,它是利用数组下标的方式判断数据是否存在的,而不是将数据实体都存储到过滤器中.所以内存的占用是非常小的.

为什么结果为0就肯定不存在?

因为,如果数据库中有这个数据,那么在我们进行数据库数据添加到过滤器操作的时候,肯定会把这个位置改为1,既然我们没有改,证明没有任何一个数据的哈希值是这个位置的下标,所以肯定不存在

结果为1,这里我们用到了 可能存在,为什么是可能而不是肯定存在呢?

因为布隆过滤器具有一定的错误率.
在上文中的缺点中我们提到了这个错误率.
那么为什么会有错误率呢?

简单来说,就是哈希碰撞.

就是两个不同的数据计算出来的哈希值可能是相同的,那比如,我们存储了id为1的商品数据,计算出来的哈希值为5, 这时候请求过来的数据id为105 计算出来的哈希值也是5,那我们只能说105可能存在而不是肯定存在.但是如果是0,那么肯定不存在.哈希碰撞是肯定存在的.

如何降低错误率

有如下的几种方法:
1.加大数组长度,尽量避免出现在相同的位置.
2.使用适当多的哈希函数来计算多个哈希值

这里提供两个公式
其中n为数据个数,m为数组长度,k为函数个数 p为错误率
计算适量的数组长度
在这里插入图片描述

计算适当的哈希函数个数
在这里插入图片描述

布隆过滤器的使用位置

在这里插入图片描述

通常的人会理解放在Redis之后,数据库之前. 反正就是为了避免去访问数据库嘛,放在数据库前面不就好了??

No No No!!!

放在数据库之前是不假,但是如果能更优化,何必要放弃呢?
我们放在服务器这里,就可以避免后边的调用链路,节省服务器的资源.

如果您对文章有更好的指正,期待您不吝赐教!

欢迎关注本人微信公众号鹏Public
在这里插入图片描述

获取更多有趣的见闻,奇怪的知识,有用的内容!!

博客与公众号将尽量保持同步更新,随时获取新鲜内容!

我们一同成长!

文章到此结束,如果您有更好的指正,还请您不吝赐教!感谢您的阅读!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值