到底什么是缓存穿透,缓存雪崩,缓存击穿

什么是缓存穿透


缓存穿透是指查询一个一定不存在的数据,由于缓存没有命中,这时候我们会数据库查询。出于容错考虑,当我们从数据库查询不到数据的时候,则不会写入缓存,这个可能导致每次请求都去数据库查询,失去了缓存的意义。在流量大的时候DB可能就会挂掉,如果有人利用这个不存在key频繁操作攻击我们的应用,这就是漏洞。
以查询用户信息为例,id=-1的用户是肯定不存在的,但是现在有10000个请求,其中9000个都是请求id=-1的这个用户,我们的数据库很容易的就被打死。

缓存穿透解决办法

  1. 简单粗暴,如果我们查询数据库结果为null的话,我们直接把这个null缓存起来,并且设置一个很短的过期时间。
  2. 以用户为例,我们把所有的用户id缓存到一个足够大的bitmap中,访问这个不存在的key的时候就行拦截,从而避免对数据库造成的压力
  3. 设置布隆过滤器(以后单开一篇博客介绍)

什么是缓存雪崩


数据未加载到缓存;缓存同一时刻大面积失效或者宕机,从而导致所有请求都去查询数据库,造成数据库CPU负载夜里过高,甚至宕机;都会造成缓存雪崩。
简单来说的话,就是因为缓存未命中或者缓存系统的宕机,从而引起数据库宕机成为缓存雪崩

如何解决缓存雪崩

  1. 如果针对缓存未加载或者缓存失效,那么尽量让缓存失效时间尽量分布均匀
  2. 如果针对缓存系统崩溃的话,可以构建redis主从模式+哨兵、redis cluster,避免全盘崩溃
  3. hystrix熔断器做保护,避免MySQL被打死

缓存穿透和缓存雪崩的区别

好像缓存穿透和缓存雪崩有点相似,都是缓存没有查询到去查询数据库造成的宕机。但是这两点是有区别的,缓存穿透是查询一个一定不存在的数据,而缓存雪崩其中一点是查询的数据是存在于数据库中的,一定不要搞混了。

缓存击穿


针对某一个key,我们设置了过期时间的key而失效,或者还未加载,如果某一时间被超高频率的访问,也有可能会造成数据库挂掉。与缓存雪崩相比,雪崩针对的是以系列key,而击穿是针对一个key。
比如10点的时候要去抢购一个手机,10点这一刻有N多请求访问服务器,并且这时候我们的数据还没有加入到缓存中,导致所有请求都去数据库查询,这样数据库就很容易挂掉。

如何解决缓存击穿

  1. 让key一直存在
  2. 使用互斥锁
if (key不存在){
		if(tryLock()) {
				数据库查询
				释放锁
				返回数据
		} else {
				while(!tryLock()) {
                    Thread.sleep(100);	//暂停一会,防止cpu空转
				}
				查询缓存,写入数据
		}
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值