缓存穿透
**缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。**在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。
解决方案
1、最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。
2、接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
3、从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击
缓存雪崩
缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩。
解决方案
1、缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
2、如果缓存数据库是分布式部署,将热点数据均匀分布在不同的缓存数据库中。
3、设置热点数据永远不过期。
如果已经发生了雪崩怎么办?
如果流量不是很大,你的 db 扛住了,恭喜你度过难关,当然这只是侥幸,哪天运营做了一个大活动,还是逃脱不掉,那么我们该怎么办呢?
其实就是限流,防止过多流量流入 db,保护 db 的正常请求。
其实也可以直接通过限流算法,如令牌或者漏桶算法,限制当前查询 key 的多少流量能到达 db。
缓存击穿
对于一些设置了过期时间的key,如果这些key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。这个时候,需要考虑一个问题:缓存被“击穿”的问题,这个和缓存雪崩的区别在于这里针对某一key缓存,前者则是很多key。
缓存在某个时间点过期的时候,恰好在这个时间点对这个Key有大量的并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。
1、设置热点数据永远不过期。
2、利用分布式锁,来保证,当前查询的 key,只能一个流量去 db 查询,查询结果后,再放入 cache,其他请求在这个过程中没有抢锁,就会阻塞,或者你设置一个超时时间,如果超时时间内,没有返回,那么直接返回空,或者进行重试,重试次数不能太多,防止服务资源占用过多,造成服务雪崩。这样通过分布式锁就限制了大部分流量流入 db 了,从而保护了 db。

本文探讨了缓存系统中可能出现的三种问题:缓存穿透、雪崩和击穿。缓存穿透是指查询不存在的数据导致频繁访问数据库;解决方案包括使用布隆过滤器、接口校验和设置key-null。缓存雪崩是大量缓存在同一时间过期,导致数据库压力过大;解决办法包括设置随机过期时间、分布式部署和热点数据不过期。缓存击穿是热点key过期时的并发访问;处理方式包括让热点数据不过期或利用分布式锁限制流量。
1万+

被折叠的 条评论
为什么被折叠?



