一 、缓存穿透
定义
查询一个不存在的数据,在缓存中查不到数据,也不会写入缓存,导致每次都查询数据库
解决方案
- 解决方案一:当查询是null时候也进行缓存。
- 优点:简单方便。
- 缺点:消耗内存,可能导致不一致问题。
- 解决方案二:布隆过滤器。
-
优点:内存占用少,没有多余key。
-
缺点:实现复杂。有可能存在误判。
- 位图:相当于一个以bit为单位的数组,数组中每个单元只能存储二进制数0或1。
- 布隆过滤器作用:可以用来检索一个元素是否在一个集合中。
-
二、缓存击穿
定义:
给一个key设置了过期时间,当key过期的时候恰巧这个时间点对这个key有大量的并发请求,这些请求可能会瞬间把DB压垮。
解决方案
-
解决方案一:互斥锁。当thread1在未命中缓存,进行缓存重建时其他线程无法获取锁,持续休眠直到thread1重建完成后释放锁。
- 优点:可以保证强一致性。
- 缺点:性能比较差。
-
解决方案二:逻辑过期:热点的key在redis中不设置过期时间,再婚存数据中加入过期时间字段描述此数据是否过期,thread查询缓存判断是否逻辑过期,如果过期获取互斥锁,新建一个线程去构建缓存。当前线程继续返回过期数据。
- 优点:可以保证高可用性,性能较好。
- 缺点:无法保证强一致性。
三、缓存雪崩
定义
同一时间大量缓存 key同事失效过着redis服务宕机,导致大量请求到达数据库,带来巨大压力。
场景一:大量key过期
解决方案
- 给不同的key的ttl添加随机值。
场景二:redis服务宕机
解决方案
- 提高redis集群的高可用性 哨兵模式、集群模式,详细见下文链接。
哨兵模式,集群脑裂 - 设计业务系统时添加降级限流策略。NGINX,gateway。
- 给程序添加多级缓存。