缓存雪崩、穿透、热点key

缓存雪崩

  • 概念

由于缓存失效,致使请求直接命中数据库。致使 DB 负荷大增,最终宕机。redis

  • 如何解决

1)缓存高可用数据库

经过搭建缓存的高可用,避免缓存挂掉致使没法提供服务的状况,从而下降出现缓存雪崩的状况。缓存

假设咱们使用 Redis 做为缓存,则可使用 Redis Sentinel 或 Redis Cluster 实现高可用。服务器

2)本地缓存网络

若是使用本地缓存(Ehcache、Guava Cache )时,即便分布式缓存挂了,也能够将 DB 查询到的结果缓存到本地,避免后续请求所有到达 DB 中。数据结构

3)请求 DB 限流(Guava RateLimiter、Sentinel)分布式

经过限制 DB 的每秒请求数,避免 DB 宕机。这样至少能有两个好处:线程

可能有一部分用户,还可使用,系统还没死透。
将来缓存服务恢复后,系统当即就已经恢复,无需在处理 DB 也挂掉的状况。对象

4)服务降级(Hystrix、Sentinel)blog

若是请求被限流,或者请求 DB 超时,咱们能够服务降级,提供一些默认的值,或者友情提示。

缓存穿透

缓存穿透,是指查询一个不存在的数据,当缓存不命中时,会从 DB 查询到数据,再更新到缓存中,而且处于容错考虑,若是从 DB 查不到数据则不写入缓存,这将致使这个不存在的数据每次请求都要到 DB 去查询。

在流量大时,可能 DB 就挂掉了,要是有人利用不存在的 key 频繁攻击咱们的应用,这就是漏洞。好比使用程序瞬间产生大量的请求,攻击服务器。

  • 如何解决
  1. 方案一,缓存空对象:当从 DB 查询数据为空,咱们仍然将这个空结果进行缓存,具体的值须要使用特殊的标识,能和真正缓存的数据区分开。另外,须要设置较短的过时时间,通常建议不要超过 5 分钟。可是当客户端同一时刻发起大量请求时,会致使redis垃圾缓存过多,可能致使redis宕机。我的认为客户端同一时刻发起大量请求时,应该使用限流机制,避免大量垃圾请求进入后台。若是不少客户端发起DDOS攻击,就不太好防了。

  2. 方案二,使用互斥锁排队(或者分段锁),即根据key获取value值为空时,锁上,从数据库中load数据后再释放锁。若其它线程获取锁失败,则等待一段时间后重试。这里要注意,分布式环境中要使用分布式锁,单机的话用普通的锁(synchronized、Lock)就够了。

  3. 方案三,此方案摘自网络,BloomFilter 布隆过滤器:在缓存服务的基础上,构建 BloomFilter 数据结构,在 BloomFilter 中存储对应的 KEY 是否存在,若是存在,说明该 KEY 对应的值为空。那么整个逻辑的以下:

    一、根据 KEY 查询缓存。若是存在对应的值,直接返回;若是不存在,继续向下执行。

    二、根据 KEY 查询在缓存 BloomFilter 的值。若是存在值,说明该 KEY 不存在对应的值,直接返回空;若是不存在值,继续向下执行。

    三、查询 DB 对应的值,若是存在,则更新到缓存,并返回该值。若是不存在值,更新到缓存 BloomFilter 中,并返回空。

热点key

在实际请求中,可能存在热点key的状况,致使缓存宕机。好比某个流量明星微博发了某条信息,几千万人都在看,这条微博就会成为热点key。

  • 如何解决

识别热点key,如发现是热点key,缓存到本地。同时作好熔断、降级处理。盗用网络的一张图片(不记得出处了),以下:

相关文章
相关标签/搜索