【redis】- 缓存击穿、缓存穿透、缓存雪崩


在这里插入图片描述

缓存穿透

概念

查询一个不存在的数据,缓存未查到之后就去数据库查询;查不到数据就不写入缓存,导致每次查询这个数据都会从数据库查。

后果

如果有些不怀好意的人,利用这个不存在的数据,频繁大量的访问你的数据库,产生大量的请求,极有可能导致你的数据库异常访问不了、数据库宕掉。

解决方案

方案一
  • 缓存空对象:
  • 缓存空对象导致的问题:

1、空值做了缓存,意味着缓存层中存了更多的键,需要更多的内存空间 ( 如果是攻击,问题更严重 ),比较有效的方法是针对这类数据设置一个较短的过期时间,让其自动剔除。
2、缓存层和存储层的数据会有一段时间窗口的不一致,可能会对业务有一定影响。例如过期时间设置为 5 分钟,如果此时存储层添加了这个数据,那此段时间就会出现缓存层和存储层数据的不一致,此时可以利用消息系统或者其他方式清除掉缓存层中的空对象。

  • 伪代码:
String get(String key){
	// 从缓存中获取数据
	String cacheValue = cache.get(key);
	// 缓存为空
	if(StringUtils.isBlank()){
	// 从存储中获取
	String storageValue = storage.get(key);
	// 如果存储数据为空,需要设置一个过期时间
	if(storageValue == null){
		cache.expire(key,60);
	}			
		return storageValue;
	}else{
		// 直接返回缓存中的值
		return cacheValue;
	}
}
方案二
  • 布隆过滤器:

是一个很长的二进制向量和一系列随机映射函数。

  • 原理:

存入过程:
通过K个哈希函数计算该数据,返回K个计算出的hash值;
这些K个hash值映射到对应的K个二进制的数组下标;
将K个下标对应的二进制数据改成1。

查询过程:
通过K个哈希函数计算该数据,对应计算出的K个hash值;
通过hash值找到对应的二进制的数组下标;
判断:如果存在一处位置的二进制数据是0,那么该数据不存在。如果都是1,该数据存在集合中。

删除过程:
一般不能删除布隆过滤器里的数据。

  • 优点:

由于存储的是二进制数据,所以占用的空间很小;
插入和查询速度是非常快的,时间复杂度是O(K);
保密性很好,因为本身不存储任何原始数据,只有二进制数据。

  • 缺点:

(1)存在误判:
添加数据是通过计算数据的hash值,那么很有可能存在这种情况:两个不同的数据计算得到相同的hash值。
(2)删除困难:
如果两个数据的hash值一样,删除的时候会将两个数据都删除掉。

缓存击穿

概念

当某个热点数据在缓存中突然失效.导致大量的用户直接访问数据库.导致并发压力过高造成异常。

后果

造成某个时刻所有访问直接打在数据库上,导致数据库压力剧增。

解决方案

方案一:
设置为永不过期。

方案二:
使用互斥锁。如果缓存失效的情况,只有拿到锁才可以查询数据库,降低了在同一时刻打在数据库上的请求,防止数据库打死。当然这样会导致系统的性能变差。

缓存雪崩

概念

大量数据key失效,导致大量数据打到数据库。

原因

redis宕机;设置了相同的过期时间。

后果

导致缓存、数据库等一系列服务宕机

解决方案

在缓存时给过期时间加一个随机值;避免了因为采用相同的过期时间导致的缓存雪崩.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值