【Redis】缓存穿透详解

1.引言

用户数据通常存储在数据库中,而数据库的数据则保存在磁盘上。由于磁盘的读写很慢,为了避免用户直接访问数据库,我们可以使用 Redis 作为缓存层。

Redis 是一个内存数据库,可以将数据库中的数据缓存在 Redis 中,这样数据就存储在内存中,而内存的读写速度比硬盘快几个数量级,从而显著提升系统性能。

引入缓存层后,会出现三种缓存异常问题:缓存穿透缓存击穿缓存雪崩,这篇文章主要探讨缓存穿透的问题。

想要了解缓存击穿和缓存雪崩,可以看我的这篇博客:【Redis】缓存击穿与缓存雪崩:问题与解决方案


2.缓存穿透

2.1 概念

缓存穿透指的是请求的数据在缓存中不存在,并且数据库中也没有,没办法构建缓存数据来服务后续的请求。那么当有大量这样的请求到来时,则会造成数据库压力增加,甚至可能导致数据库崩溃。

2.2 造成的原因

1)请求的 key 不存在:用户请求的数据在数据库和缓存中都不存在,例如,恶意用户构造大量不存在的 key,导致每次请求都绕过缓存,直接查询数据库。

2)缓存未命中:某些合法请求可能因为缓存过期或被清除而无法命中缓存,这种情况下,如果请求频率很高,就会导致大量请求直接查询数据库。

3)不合理的缓存策略:如果没有对空值进行缓存,即请求的数据不存在,系统会频繁查询数据库,造成缓存穿透。

2.3 解决方案

1)限制非法请求

在 API 入口处我们要判断求请求参数是否合理,请求参数是否含有非法值、请求字段是否存在,如果判断出是恶意请求就直接返回错误,避免进一步访问缓存和数据库。

局限性
1.仅依靠参数校验可能无法检测到所有类型的恶意请求,有些攻击者可以伪造合法请求的参数,绕过这些校验。

2.如果请求参数非常复杂,校验逻辑可能会变得繁琐,增加了实现和维护的难度,且可能导致性能下降。

3.即使请求参数合理,频繁的合法请求仍可能导致缓存穿透的问题,特别是在流量突增的情况下。


2)缓存空对象

对于某些经常请求但不存在的数据,可以在缓存中存储空值设定较短的过期时间,后续请求就可以从缓存中读取到空值或者默认值,返回给应用,而不会继续查询数据库。

局限性

1.数据不一致性问题:如果数据源中的实际数据发生变化(如新增或删除),但缓存中的空值未能及时更新,可能导致后续请求仍返回空值。并且在高并发环境下,多个请求可能同时修改数据状态,导致缓存与数据库状态不一致。如果某个请求更新了数据库,但另一个请求仍从缓存中获取空值,将引发数据不一致。

2.冗余存储:缓存空值会造成额外的内存消耗。


3)布隆过滤器

在写入数据库数据时,使用布隆过滤器做个标记,然后在用户请求到来时,业务线程确认缓存失效后,通过查询布隆过滤器快速判断数据是否存在,如果不存在,就不用通过查询数据库来判断数据是否存在。
使用布隆过滤器流程图


布隆过滤器

布隆过滤器使用一个较大的 bit 数组来保存所有的数据,数组中的每个元素都只占用 1 bit ,并且每个元素只能是 0 或者 1。

当一个元素加入布隆过滤器中的时候:使用布隆过滤器中的哈希函数对元素值进行计算,得到哈希值(有几个哈希函数得到几个哈希值)。根据得到的哈希值,在位数组中把对应下标的值置为 1。

当我们需要判断一个元素是否存在于布隆过滤器的时候,会进行如下操作:对给定元素再次进行相同的哈希计算;得到值之后判断位数组中的每个元素是否都为 1,如果值都为 1,那么说明这个值在布隆过滤器中,如果存在一个值不为 1,说明该元素不在布隆过滤器中。

布隆过滤器简单原理图如下:
布隆过滤器原理图
如图:不同的字符串可能哈希出来的位置相同,这种情况我们可以适当增加位数组大小或者调整我们的哈希函数。

结果:布隆过滤器说某个元素存在,小概率会误判。布隆过滤器说某个元素不在,那么这个元素一定不在。


局限性

1.误判问题:布隆过滤器可能会错误地返回某个元素存在于集合中,尽管它实际上并不在集合中。这是因为多个元素可能被映射到相同的位数组位置。理论情况下添加到集合中的元素越多,误判的可能性就越大。并且,存放在布隆过滤器的数据不容易删除。

2.无法删除元素:标准布隆过滤器无法从集合中删除已添加的元素,因为删除操作会影响位数组的状态,可能导致无法准确判断其他元素的存在。

3.固定大小:布隆过滤器的大小是固定的,初始化时需要确定位数组的大小。如果实际需要存储的元素数量超过预期,可能会增加误判率。虽然可以通过调整哈希函数数量和位数组大小来降低误判率,但这需要提前估算。

4.哈希函数的选择:布隆过滤器的性能高度依赖于哈希函数的选择。如果哈希函数不够随机,可能导致位数组中有较多冲突,增加误判率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值