缓存穿透

问题描述

系统引入redis缓存后,一个请求进来后,会先从redis缓存查询缓存有就直接返回缓存没有就去db查询db中如果有就会将其丢到缓存中,但是有些key对应数据db中并不存在,每次针对此次key请求缓存中取不到,请求都会压到db,从而可能压垮db

比如用一个不存在用户id获取用户信息,不论缓存还是数据库没有,若黑客利用大量此类攻击可能压垮数据库

解决方案

(1)对空值缓存

如果一个查询返回数据为空(不管数据库是否存在),我们仍然把这个结果null)进行缓存,给其设置一个很短的过期时间,最长不超过五分钟

(2)设置访问的名单(白名单

使用redis中的bitmaps类型定义一个可以访问的名单,名单id作为bitmaps的偏移量,每次访问bitmap里面id进行比较,如果访问id不在bitmaps里面,则进行拦截,不允许访问

(3)采用布隆过滤器

布隆过滤器(Bloom Filter)是1970年有布隆提出的,它实际上是一个很长的二进制向量(位图)和一系列随机映射函数哈希函数)。

布隆过滤可以用于检测一个元素是否在一个集合中,它的优点是空间效率和查询的世界都远远超过一般的算法,缺点是有一定的误识别率和删除困难。

将所有可能存在数据哈希到一个足够大的bitmaps中,一个一定不存在数据会被这个bitmaps拦截掉,从而避免了对底层存储系统查询压力。

(4)进行实时监控

发现redis的命中率开始急速降低,需要排查访问对象和访问的数据,和运维人员配合,可以设置黑名单限制对其提供服务比如:IP黑名单

缓存击穿

问题描述

redis某个热点key访问量很高的key过期,此时大量请求同时过来,发现缓存中没有命中,这些请求都打到db上了,导致db压力瞬时大增,可能会打垮db,这种情况成为缓存击穿

缓存击穿出现的现象:

解决方案

key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据,这个时候,要考虑一个问题:缓存被“击穿”的问题,常见解决方案如下

(1)预先设置热门数据,适时调整过期时间

redis高峰之前,把一些热门数据提前存入到redis里面,对缓存中的这些热门数据进行监控实时调整过期时间

(2)使用

缓存中拿不到数据的时候,此时不是立即去db查询,而是去获取分布式锁(比如redis中的setnx),拿到锁再去dbload数据;没有拿到锁的线程休眠一段时间重试整个获取数据方法

缓存雪崩

问题描述

key对应的数据存在,但是极短时间内有大量的key集中过期,此时若有大量的并发请求过来,发现缓存没有数据,大量的请求就会落到db上去加载数据,会将db击垮,导致服务奔溃。

缓存雪崩与缓存击穿区别在于:前者是大量的key集中过期,而后者是某个热点key过期

解决方案

(1)构建多级缓存

nginx缓存+redis缓存+其他缓存(ehcache等)

(2)使用锁或队列

加锁或者队列方式来保证不会有大量的线程数据库一次性进行读写,从而避免失效时大量的并发请求落到底层存储系统上,不适用高并发情况。

(3)监控缓存过期,提前更新

监控缓存,发下缓存快过期了,提前对缓存进行更新

(4)将缓存失效时间分散开

比如我们可以在原有的失效时间基础上增加一随机值,比如1-5分钟随机,这样缓存的过期时间重复率就会降低,就很难引发集体失效事件

原文地址:https://blog.csdn.net/qq_43745578/article/details/134741257

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_26984.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注