什么是缓存穿透:
缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时被动写的,并且当存储层查不到数据则不写入缓存,最后将导致这个不存在的数据每次请求都会到存储层去查询,失去了缓存的意义,在流量大时,可能DB就崩了导致整个微服务应用挂掉
简单来说:
一个服务器有上百万的流量请求时,如果这些请求的数据在redis缓存这一层不存在,那么就会穿过redis的缓存直达到后台,也就是mysql服务器,导致整个微服务应用挂掉
缓存穿透解决方案
1.采用布隆过滤器,将所有可能存在的数据,放到一个足够大的bitmap中,一个一定不存在的数据会被bitmap拦截掉
2.当一个数据为空时,就把它放到缓存中,但时间保存时间比较短,最长不超过五分钟。
什么是 缓存雪崩:
比如当网站首页的key失效时间都是晚上12点,但正好赶上双11,本来缓存可以抗住每秒5000个请求,但有6000的请求,可是缓存的key都失效了,大量的请求此时 1 秒 6000 个请求全部落数据库,数据库崩溃了,但当重启时又立刻被流量打死了
简单的来说:
缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩
缓存雪崩解决方案:
在批量往Redis存数据的时候,把每个Key的失效时间都加个随机值就好了,这样可以保证数据不会在同一时间大面积失效了!
缓存击穿
缓存在某个时间点过期的时候,恰好在这个时间点对这个Key有大量的并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。
"提前"使用互斥锁(mutex key)
在value内部设置1个超时值(timeout1), timeout1比实际的memcache timeout(timeout2)小。当从cache读取到timeout1发现它已经过期时候,马上延长timeout1并重新设置到cache。然后再从数据库加载数据并设置到cache中。
“永远不过期”
这里的“永远不过期”包含两层意思:、
(1) 从redis上看,确实没有设置过期时间,这就保证了,不会出现热点key过期问题,也就是“物理”不过期。
(2) 从功能上看,如果不过期,那不就成静态的了吗?所以我们把过期时间存在key对应的value里,如果发现要过期了,通过一个后台的异步线程进行缓存的构建,也就是“逻辑”过期
关于key:
key是一个字符串,通过key获取redis中保存的数据
Key(键):
keys * --列出当前库的所有key
exists key --判断某个key是否存在
move key db --移除当前库并复制到指定库
expire key -- 给指定的key设置过期时间(秒钟)
ttl key --查看还有多少秒过期(-1表示永不过期-2表示已过期)
type key --查看key是什么数据类型