最全面的Redis缓存雪崩、击穿、穿透问题解决方案

缓存穿透

用户不断发起请求缓存和数据库中都没有的数据。
我们数据库的 id 都是1开始自增上去的,如发起为id值为 -1 的数据或 id 为特别大不存在的数据。每次都能绕开Redis直接打到数据库,数据库也查不到,每次都这样,并发高点就容易崩掉了

image.png

处理缓存穿透

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都拉黑

流程图:

image.png

缓存击穿

缓存击穿是指一个Key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个完好无损的桶上凿开了一个洞。

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

2.互斥锁
我们可以在第一个查询数据的请求上使用一个 互斥锁来锁住它。
其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。后面的线程进来发现已经有缓存了,就直接走缓存。

 缓存雪崩

当某一时刻发生大规模的缓存失效的情况,会有大量的请求进来直接打到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 不会被大量的请求给打死。

流程图:

image.png

  • 25
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值