首页新闻找找看学习计划

布隆过滤器是如何解决缓存穿透问题的

0
悬赏园豆:200 [已解决问题] 解决于 2019-08-21 09:29

请问布隆过滤器(Bloom Filter)是如何解决缓存穿透(cache penetration)问题的?

dudu的主页 dudu | 高人七级 | 园豆:41069
提问于:2019-08-20 13:21
< >
分享
最佳答案
3

缓存穿透应该是 当数据库中没有某个key对应的value时,缓存中也不会有该value的缓存。所以大量的对该value的查询该的请求会绕过缓存,直接查询数据库。

缓存中一般存的是 key+value ,但是布隆过滤器却可以告诉你 key 对应的value在数据库中存不存在,如果不存在就不用查询数据库了。

拿redis为例子:
请注意,用 redis 也可以做到判断 key 对应的value 在数据库中存不在,那就是把数据库里的所有value对应的key都储存在redis 中,而value可以为空,然后判断下key.IsExists()就可以了,但是这无疑会浪费大量空间,因为存储了数据库中所有的key。而且这也不符合缓存的初衷:咱不能暴力的把所有key都存下来,而是查询了啥key,我们缓存啥key。

而布隆过滤器是一种非常高效的数据结构,把所有数据库的value对应的key 存储到布隆过滤器里,几乎不消耗什么空间,而且查询也是相当的快!但是请注意,它只能判断 key 是否存在(而且会有一定的误差)。

所以一个查询先通过布隆顾虑器判断key是否存在(key 对应的value是否存在数据库中),如果不存在直接返回空就好了。

那么布隆过滤器是怎么做到几乎不消耗空间来储存所有的key,并快速判断特定的key是否存在呢?

其实原理很简单,布隆过滤器 只是一个 byte数组,再加上几个映射函数。

每个key 都通过一系列映射函数,得到一系列的的值k,然后在这个byte数组上的把k下标的值变成1。

当要判断key是否存在时,通过映射函数映射得到的一系列k,查看byte数组相应下标k对应的值是否为1,如果有一个不为1,那么一定不存在。如果都是1 ,那么可能存在。为什么可能而不是一定呢?因为这是一个误差问题,有可能别的key把某个k的位置变成了1,key越多时,误差越大。但是放心不会很大的,这是可以控制的,byte数组越长,误差越小。

收获园豆:180
Shendu.CC | 小虾三级 |园豆:1965 | 2019-08-20 16:15

布隆过滤器是放在查询缓存之前还是放在查询数据库之前?

dudu | 园豆:41069 (高人七级) | 2019-08-20 16:48

@dudu: 放在查询缓存之前。

Shendu.CC | 园豆:1965 (小虾三级) | 2019-08-20 17:01

如果只是对少数不存在的 key 进行大量请求,只要针对不存在的 key 进行空值缓存就行了,不一定要用布隆过滤器。如果是对大量不同的不存在的 key 进行大量请求,布隆过滤器发威的时候就到了。

dudu | 园豆:41069 (高人七级) | 2019-08-21 09:28
其他回答(1)
0

实际项目上没用过,应该是构造一个布隆过滤器放入存储层全部数据,如果缓存找不到过下布隆过滤器,没查到那一定不存在在存储层,查到再去存储层查。但是没办法删除数据这个不好解决,估计使用场景也有限吧。

收获园豆:20
水墨的心 | 园豆:361 (菜鸟二级) | 2019-08-20 14:12
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册