文章目录
- 缓存问题
- 缓存穿透
- 引入
- 解决方案
- 缓存雪崩
- 缓存击穿
缓存问题
使用缓存时常见的问题主要分为三个:缓存穿透
、缓存雪崩
、缓存击穿
。
下面对其进行一一学习
缓存穿透
引入
定义
:缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样的缓存永远不会生效,这些请求都会打到数据库。
导致缓存击穿的原因是,当用户使用不存在的请求访问缓存的时候,因为缓存中不存在数据,则会将请求打到数据库,然后数据库也没有相关请求的数据,则只能给用户端报错或返回空值。一次这样无效的请求服务器还应对的过来,然而当一些(不怀好意的)人使用大量这种无效的请求访问时,则会全部打到数据库,导致数据库宕机,或者拖慢其他正确请求的访问。
那么,如何应对这种问题呢?
解决方案
常见的解决缓存击穿的方案有以下几种:
-
缓存空对象:当一个无效请求打到数据库查询无效时,将此次请求进行缓存,并赋予null值
- 优点:实现简单,维护方便
- 缺点:① 额外的内存消耗 ② 可能造成短期的不一致
-
布隆过滤
- 优点:内存占用较少,没有多余key
- 缺点:① 实现复杂 ② 存在误判可能
-
增强id的复杂度
-
做好数据的基础格式校验
-
加强用户权限校验
缓存雪崩
定义
:缓存雪崩是指在同一时间段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。
通常的解决方案有以下四种:
- 给不同的Key的TTL添加随机值(防止大量TTL同时到期)
- 利用Redis集群提高服务的可用性
- 给缓存业务添加降级限流策略
- 给业务添加多级缓存
缓存击穿
定义
:缓存击穿问题也叫热点问题,就是一个被高并发访问
且缓存重建业务较复杂
的Key突然失效,无数的请求访问会在瞬间给数据库带来巨大的冲击。
常见的解决方案有两种:
-
互斥锁(保证一致性)
- 优点:① 没有额外的内存消耗 ② 保证一致性 ③ 实现简单
- 缺点:① 线程需要等待,性能受到影响 ② 可能有死锁风险
-
逻辑过期(保证可用性)
- 优点: 线程无需等待,性能较好
- 缺点:① 不保证一致性 ② 有额外内存消耗 ③ 实现复杂