缓存雪崩

当某一时刻产生大规模的缓存生效的状况,会有大量的申请进来间接打到DB下面

解决缓存雪崩

1.redis的key在同一时间大面积生效,可思考:

  • 在批量往Redis存数据的时候,把每个Key的生效工夫都加个随机值,这样能够保证数据不会在同一时间大面积生效
setRedis(Key,value,time + Math.random() * 10000);
  • 设置热点数据不设置过期工夫,有更新操作就更新缓存就好了

2.redis挂了,可思考:

  • 应用集群缓存,保障缓存服务的高可用
    这种计划就是在产生雪崩前对缓存集群实现高可用,如果是应用 Redis,能够应用 主从+哨兵 ,Redis Cluster 来防止 Redis 全盘解体的状况。
  • 开启Redis长久化机制,尽快恢复缓存集群
    一旦重启,就能从磁盘上主动加载数据恢复内存中的数据。

3.避免MySQL不挂,可思考:

  • ehcache本地缓存 + Hystrix限流&降级,防止MySQL被打死
    应用 ehcache 本地缓存的目标也是思考在 Redis Cluster 齐全不可用的时候,ehcache 本地缓存还可能撑持一阵。
    应用 Hystrix进行限流 & 降级 ,比方一秒来了5000个申请,咱们能够设置假如只能有一秒 2000个申请能通过这个组件,那么其 他残余的 3000 申请就会走限流逻辑。而后去调用咱们本人开发的降级组件(降级),比方设置的一些默认值呀之类的。以此来爱护最初的 MySQL 不会被大量的申请给打死。

流程图:

缓存穿透

用户一直发动申请缓存和数据库中都没有的数据。
咱们数据库的 id 都是1开始自增下来的,如发动为id值为 -1 的数据或 id 为特地大不存在的数据。每次都能绕开Redis间接打到数据库,数据库也查不到,每次都这样,并发高点就容易崩掉了

解决缓存穿透

1.接口层减少校验
比方用户鉴权校验,参数做校验,不非法的参数间接代码Return,比方:id 做根底校验,id <=0的间接拦挡等。

2.缓存空值
之所以会产生穿透,就是因为缓存中没有存储这些空数据的key。从而导致每次查问都到数据库去了。那么咱们就能够为这些key对应的值设置为null 丢到缓存外面去。前面再呈现查问这个key 的申请的时候,间接返回null。

3.布隆过滤器(Bloom Filter)
Bloom Filter是用于判断某个元素(key)是否存在于某个汇合中。先把咱们数据库的数据都加载到咱们的过滤器中,在缓存之前在加一层BloomFilter,在查问的时候先去 BloomFilter 去查问 key 是否存在,如果不存在就间接返回,存在再走查缓存,而后查DB。

4.Nginx
对单个IP每秒拜访次数超出阈值的IP都拉黑

流程图:

缓存击穿

缓存击穿是指一个Key十分热点,在不停的扛着大并发,大并发集中对这一个点进行拜访,当这个Key在生效的霎时,继续的大并发就穿破缓存,间接申请数据库,就像在一个完整无缺的桶上凿开了一个洞。

1.设置热点数据永远不过期

2.互斥锁
咱们能够在第一个查问数据的申请上应用一个 互斥锁来锁住它。
其余的线程走到这一步拿不到锁就等着,等第一个线程查问到了数据,而后做缓存。前面的线程进来发现曾经有缓存了,就间接走缓存。

参考两位大佬的文章作出的总结,大佬太强了:
《咱们一起进大厂》系列-缓存雪崩、击穿、穿透
阿里一面:对于【缓存穿透、缓存击穿、缓存雪崩、热点数据生效】问题的解决方案