提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 缓存穿透 击穿 雪崩
- 运行速度:
- 1 缓存穿透
- 问题描述:
- 如何解决:
- 2 缓存击穿
- 问题描述:
- 如何解决:
- 3 缓存雪崩
- 说明:
- 解决方案:
缓存穿透 击穿 雪崩
问题描述: 由于海量的用户的请求 如果这时redis服务器出现问题 则可能导致整个系统崩溃.
运行速度:
- tomcat服务器 150-250 之间 JVM调优 1000/秒
- NGINX 3-5万/秒
- REDIS 读 11.2万/秒 写 8.6万/秒 平均 10万/秒
1 缓存穿透
问题描述:
由于用户高并发环境下访问 数据库中不存在的数据时 ,容易导致缓存穿透.
缓存击穿是指一个Key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个完好无损的桶上凿开了一个洞。
缓存击穿的话,设置热点数据永远不过期。或者加上互斥锁就能搞定了。
如何解决:
- 热点数据永不过期
- 使用互斥锁
业界比较常用的做法,是使用mutex。简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX)去set一个mutex key,当操作返回成功时,再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法。
伪代码如下图:
SETNX,是「SET if Not eXists」的缩写,也就是只有不存在的时候才设置,可以利用它来实现锁的效果
2 缓存击穿
量太大,缓存过期
问题描述:
由于用户高并发环境下, 由于某个数据之前存在于内存中,但是由于特殊原因(数据超时/数据意外删除)导致redis缓存失效. 而使大量的用户的请求直接访问数据库.
俗语: 趁他病 要他命
如何解决:
1. 设定超时时间时 不要设定相同的时间.
2. 热点数据永不过期
3. 设定多级缓存
4.缓存空对象
当存储层不命中,到数据库查发现也没有命中,那么仍然将空对象保留到缓存层中,之后再访问这个数据将会从缓存中获取,这样就保护了后端数据源。不过空值做了缓存,意味着缓存层中存了更多的键,需要更多的内存空间(如果是攻击,问题更严重),比较有效的方法是针对这类数据设置一个较短的过期时间,让其自动剔除。
5. 使用布隆过滤器
3 缓存雪崩
缓存雪崩是指在某一个时间段,缓存集中过期失效或者Redis宕机
说明:
由于高并发条件下 有大量的数据失效.导致redis的命中率太低.而使得用户直接访问数据库(服务器)导致奔溃,称之为缓存雪崩.
缓存雪崩:由于缓存层承载着大量请求,有效地保护了存储层,但是如果缓存层由于某些原因不能提供服务,比如同一时间缓存数据大面积失效,那一瞬间Redis跟没有一样,于是所有的请求都会达到存储层,存储层的调用量会暴增,造成存储层也会级联宕机的情况。
解决方案:
- 保证缓存层服务高可用性
- 不要设定相同的超时时间 随机数 ,热点数据永不过期
- 提高redis缓存的命中率 调整redis内存优化策略 采用LRU等算法.
- 微软服务机制 API网关实现. (SpringCloudGateway 网关 限流 降级 熔断)
- 数据预热
- 设定多级缓存.
- 配置布隆过滤器