缓存常见三大问题及布隆过滤器解析

Posted 家有珞宝

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了缓存常见三大问题及布隆过滤器解析相关的知识,希望对你有一定的参考价值。

一、缓存穿透

目前大多数应用中,缓存的使用方式如以下所示:

  1. 请求首先判断缓存中是否有数据;

  2. 如果命中缓存,则直接返回数据

  3. 如果没命中缓存,则查询数据库查到数据后,再返回数据

在大多的正常业务情况下,缓存可以有效的完成业务需求,但当海量的不存在的key请求进来时,这些海量的请求都会打到数据库中,数据库压力剧增,可能会导致系统崩溃,这就是缓存穿透。

解决方案:

  1. 缓存空数据:之所以会发生缓存穿透,是因为缓存中没有存储这些空数据的key,导致请求全部打到数据库中。我们可以稍微修改一下业务系统的代码,将数据库查询结果为空的key也缓存起来,设置适当的过期时间,当后续又出现该key时缓存直接返回空,不再请求数据库。

  2. 布隆过滤器(后文会详细介绍):在查询缓存之前加一道屏障,里面存储目前数据库中存在的所有的key,如下图所示:

当业务系统有查询请求时,首先去布隆过滤器中查询该key是否存在,如果不存在直接返回空数据。如果存在,继续走后面的流程,查询缓存或者数据库再返回数据。

两种方案的比较:

对于一些恶意攻击,查询的key往外各不相同,而且数据较多。此时第一种方案就显得意义不大,因为它要存储所有的空值key,但是恶意攻击的key往往各不相同,而且同一个key往往只请求一次,即使缓存看key也起不到保护数据库的作用。

因此,对于空数据的key重复情况概率低的情况而言布隆过滤器可以更好的胜任。而对于key的数量有限,key重复请求概率较高的情况而言,缓存key可以起到更好的效果,成本也更低。

二、缓存雪崩

缓存雪崩可以理解为在某一个时间段内,缓存中的key集中过期失效,导致短期内大量请求打到数据库的情况。

解决方案:

1.避免缓存集中失效,不同的key设置不同的过期时间,同一分类的key在过期时间上增加随机因子,尽量分散缓存过期时间。

2.分布式缓存集群,将热点数据分布在不同的缓存数据库中,如redis集群

三、缓存击穿

缓存击穿是指缓存中某一个key非常热点,在不停的扛着大并发,在这个key失效的瞬间,持续的大并发就穿破缓存直接打到数据库中,和缓存雪崩不同的是缓存击穿是并发查询同一条数据而雪崩是不同的key同一时间过期。

解决方案:

1.加互斥锁在第一个请求请求数据库的过程中,其他请求等待,第一个请求从库中取到数据并写入缓存中返回,其他请求直接读取缓存。

2.设置热点数据永不过期,此种对于热点数据相对固定的情况,成本更低。

3.对于热点数据不断变化的情况可参考阿里双11万亿流量下的分布式缓存                                                     https://yq.aliyun.com/articles/290865

布隆过滤器

布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。

如果想判断一个元素是不是在一个集合里,一般想到的是将集合中所有元素保存起来,然后通过比较确定。链表、树、散列表(又叫哈希表,Hash table)等等数据结构都是这种思路。但是随着集合中元素的增加,我们需要的存储空间越来越大。同时检索速度也越来越慢,上述三种结构的检索时间复杂度分别为:O(n), O(log n), O(n/k)。

布隆过滤器的原理是,当一个元素被加入集合时,通过K个Hash函数将这个元素映射成一个位数组中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检元素一定不在;如果都是1,则被检元素很可能在。这就是布隆过滤器的基本思想。


BloomFilter的核心思想有两点:

1.多个hash,增大随机性,减少hash碰撞的概率

2.扩大数组范围,使hash值均匀分布,进一步减少hash碰撞的概率。

尽管BloomFilter已经尽可能的减小hash碰撞的概率了,但是,并不能彻底消除,
如果对应的bit位值都为1,那么也不能肯定value一定存在,但bit位存在不为1的值则value肯定不存在。

BloomFilter的应用

1.黑名单

2.网络爬虫

判断某个URL是否已经被爬取过

3.K-V系统快速判断某个key是否存在

在上述预防缓存穿透的应用中,用于在查询时快速判断某个key在缓存中是否存在,如果不存在,直接返回,节省掉后续的查询



以上是关于缓存常见三大问题及布隆过滤器解析的主要内容,如果未能解决你的问题,请参考以下文章

布隆过滤器

Redis系列之什么是布隆过滤器?

redis 十五. 缓存穿透 与布隆过滤器原理

Redis系列之什么是布隆过滤器?

Redis系列之什么是布隆过滤器?

从位图到布隆过滤器,C#实现