Redis 雪崩,穿透,击穿

缓存雪崩

假如一个系统在正常情况下(带redis缓存),每秒可以处理3000个请求,但是突然来了6000个请求,这个时候redis缓存挂了,最多就发一条信息给运维人员。然后所有的请求都落在了MySQL上,无缓存。这样子就直接导致MySQL崩了,从而导致了整个系统瘫痪,雪崩。应对方案有在雪崩前,雪崩时,雪崩后

  • 雪崩前:在雪崩前搭建一个稳定的redis缓存,例如master主从+哨兵,直到整个集群都挂掉,redis才挂
  • 雪崩时:当缓存全部挂掉时候,这个时候采取限流+服务降级,通过nginx/其他限流策略 5000个请求只接收1000/2000个请求,其余返回503或其他提示,不做处理。这样子对于系统来说,还是可以处理掉一部分请求,对于用户来说就是多刷新两次,还是可以接受的。
  • 雪崩后:然后赶紧恢复缓存
  • 随机设置过期时间
  • 设置永久有效

缓存穿透

依然是每秒突然来5000个请求,但是有大部分请求都是黑客恶意攻击,例如id顺序查询是1 2 3 4,但是黑客偏偏是从-1 -2...开始,这样子程序依然会从缓存,数据库中查询,但是这种查询是无效的。我们的做法是

  • 将空数据放入缓存,设置较短的过期时间
  • 使用布隆过滤器

缓存击穿,

就是说某个 key 非常热点,访问非常频繁,处于集中式高并发访问的情况,当这个 key 在失效的瞬间,大量的请求就击穿了缓存,直接请求数据库,就像是在一道屏障上凿开了一个洞。
不同场景下的解决方式可如下:

  • 若缓存的数据是基本不会发生更新的,则可尝试将该热点数据设置为永不过期。
  • 若缓存的数据更新不频繁,且缓存刷新的整个流程耗时较少的情况下,则可以采用基于 redis、zookeeper 等分布式中间件的分布式互斥锁,或者本地互斥锁以保证仅少量的请求能请求数据库并重新构建缓存,其余线程则在锁释放后能访问到新缓存。
  • 若缓存的数据更新频繁或者在缓存刷新的流程耗时较长的情况下,可以利用定时线程在缓存过期前主动地重新构建缓存或者延后缓存的过期时间,以保证所有的请求能一直访问到对应的缓存。

你可能感兴趣的:(Redis 雪崩,穿透,击穿)