zoukankan      html  css  js  c++  java
  • Redis缓存雪崩、击穿、穿透

    一、缓存三大问题

    这三个问题一旦发生,就会导致大量请求进入后台的数据库,如果有大量并发同时到达数据库,有可能会导致数据库宕机,影响业务,也有可能会导致一系列连锁反映,很可能导致业务长时间无法恢复。

    接下来本文详细介绍这三个问题的发生场景以及对应的解决方案。

    二、缓存雪崩

    2.1 雪崩场景

    雪崩是指大量请求无法在redis进行处理,原本预期在redis的中存在的数据却在redis中不存在,紧接着这些请求被全部转发到了数据库,导致暑数据库压力大增。产生雪崩的原因主要有两个:

    1. 缓存中有大量的数据同时过期,导致大量请求无法在redis中无法处理。
    2. Redis宕机

    2.1 应对方案

    针对缓存中有大量的数据同时过期的应对方案

    1. 避免给大量业务数据设置相同的过期时间,业务场景中总会出现同时实效的case,比如基于订单的下单时间。对于这种场景,可以在过期时间后面加个随机的时间比如(1-3分钟)。这样既保证了业务基本在相近的时间过期,也不会在同时间集中过期。
    2. 降级,如果雪崩已经产生,可以对业务进行降级,非核心数据直接返回指定的静态数据(缓存中没有也不去数据库请求),只有核心数据持续访问缓存(如果缓存没有,也可以去访问数据库,由于限制了非核心数据的请求,这个时候db的压力应该不大)。

    针对Redis宕机应对方
    redis宕机就等于所有数据同时失效,等于最强雪崩,redis所能承载的qps是万级别,而单个数据库所能承载的qps是千级别,这个时候如果所有请求全部进入DB,必然会导致DB的奔溃。有两个处理方法。

    1. 服务彻底熔断,当前进来后直接返回,不再访问数据库,对服务使用方来说,整个服务是不可用的,对业务的影响最大,但是彻底保护了数据库。

    2. 请求限流,在业务系统的请求入口控制每秒进入服务的次数,限流的比例可以基于之前的数据进行分析,比如在雪崩前入口的qps是10000,其中9000被redis承载,1000进入了数据库(说明数据库能承载1000的qps),那么这个时候可以将入口的qps 限制为1000,这样既保证了数据库的安全,也不至于业务不可用(部分可用状态)。限流示意图如下。

    3. 主从集群部署,实现redis的高可用,当主节点宕机后从节点可以切换为主节点继续提供服务。

    当然宕机后的一系列处理方法同样适用于大量key同事过期的case。

    三、缓存击穿

    3.1 击穿场景

    热点数据在redis中找不到,和雪崩相比,击穿对应的热点数据数据量比较小,但是这些数据的请求量非常高,导致大量请求都被大到了数据库。
    击穿发生在热点数据失效时。

    3.2 应对方案

    对于缓存击穿解决方案比较简单,对于热点数据可以设置永不过期,这样就解决了失效问题。

    四、缓存穿透

    4.1 穿透场景

    缓存穿透是指查询的数据既不在缓存也不在数据库,请求redis时候发现缓存缺失,再去访问数据库,发现数据库也没有,所以无法补全缓存数据,导致每次查询都会去请求数据库,当有
    大量类似的请求场景时候,也会对数据库造成巨大的压力。
    发生穿透的场景:

    1. 业务误操作导致本应该存在的数据被误删除
    2. 恶意攻击,专门查询数据库中没有的数据,利用穿透的漏洞。
    3. 设计问题,代码不严谨,已知可能为空的数据没有去做判断。

    4.2 应对方案

    有三个方法可以解决穿透问题。

    1. 给缓存赋空值或者缺省值,一旦发现没有业务数据,可以赋为空置或者留一个标示值,比如有值的时候对应的值是一个list,如果发现没有业务数据可以付一个空的list,这样等下次再来访问时,发现redis已经有缺省值,可以直接返回,避免了多次访问数据库。
    2. 通过业务规则判断,如果通过某些规则就可以知道没有数据,则可以直接不用访问。
    3. 使用布隆过滤器,可以快速判断数据是否存在,避免从数据库中查询是否存在,减轻数据库的压力。原理和相关使用后期专门写一篇文章介绍。

    本文完。

    作者:iBrake
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    Eureka的工作原理以及它与ZooKeeper的区别
    利用javascript判断文件是否存在
    带jsk证书,请求https接口
    C# .net 数组倒序排序
    C#中ArrayList和string,string[]数组的转换
    C#中遍历ArrayList的三种方法
    求其中同一个主叫号码的两次通话之间间隔大于10秒的通话记录ID
    启动tomcat时,一直卡在Deploying web application directory这块的解决方案
    Linux下修改Mysql的用(root的密码及修改root登录权限
    启动MySql提示:The server quit without updating PID file(…)失败
  • 原文地址:https://www.cnblogs.com/Brake/p/14364457.html
Copyright © 2011-2022 走看看