1、缓存穿透
1.1 产生原因
客户端请求的数据在缓存和数据库都不存在这样会导致这些请求都访问DB。导致DB压力瞬间变大而卡死或者宕机。
举例:当大量客户端发出http://127.0.0.1:8080/test?id=3456请求,而数据库和缓存都没有3456数据就可能导致造成缓存穿透的情况。
1.2 解决方式
接口校验
类似于用户权限的拦截,对于id=3456这些无效访问就直接拦截,不允许这些请求到达Redis、DB上。
使用布隆过滤器
使用BitMap作为布隆过滤器,将目前所有可以访问到的资源通过简单的映射关系放入到布隆过滤器中(哈希计算),当一个请求来临的时候先进行布隆过滤器的判断,如果有那么才进行放行,否则就直接拦截。【缺点:有一定误差】
对空值进行缓存
类似于上面的例子,虽然数据库中没有id=3456的用户的数据,但是在Redis中对他进行缓存(key=3456,value=null),这样当请求到达Redis的时候就会直接返回一个null的值给客户端,避免了大量无法访问的数据直接打在DB上。【缺点:大量的null值到Redis中,可能导致Redis内存占用不足的情况】
实时监控
对Redis进行实时监控,当发现Redis中的命中率下降的时候进行原因的排查,配合运维人员对访问对象和访问数据进行分析查询,从而进行黑名单的设置限制服务(拒绝黑客攻击)。
2、缓存击穿
2.1 产生原因
Redis某个热点key过期而此时有大量请求访问导致所有请求访问DB而产生卡死或者宕机。
举例:类似于 “某个公众人物做出惊天动地的事”上了热搜,这时候大量 “粉丝”访问该热点事件,但是由于某个原因热点key不存在了,那这时大量请求访问Redis而得不到响应,那么就会将请求直接打到DB上,导致整个DB瘫痪。
2.2 解决方式
提交对热点数据预热
类似于新闻、某博等软件都需要对热点数据进行预先设置在Redis中。
监控数据
监控哪些数据是热门数据,实时的调整key的过期时长。
使用互斥锁
只有一个请求可以获取到互斥锁,然后到DB中将数据查询并返回到Redis,之后所有请求就可以从Redis中得到响应。【缺点:所有线程的请求需要一同等待】
3、缓存雪崩
3.1 产生原因
Redis中大量key集体过期,这时候如果有大量并发的请求来到,Redis就无法进行有效的响应(命中率急剧下降),也会导致DB瘫痪。
缓存雪崩的场景通常有两个
大量热点key同时过期
缓存服务故障或宕机
3.2 解决方式
随机设置过期时间
常用且易于实现通过使用随机数使得key的过期时间TTL是随机的,防止集体过期。
搭建多级缓存
使用nginx + Redis + 其他缓存,可靠性更强。
使用锁
如果查不到就加上排它锁,其他请求只能进行等待,但这种方式可能影响并发量。
搭建缓存集群
主要针对缓存服务故障的情景,使用Redis集群来提高服务的可用性。
评论区