十二:redis击穿、穿透、缓存雪崩

十二:redis击穿、穿透、缓存雪崩

概念区分: 击穿、穿透、雪崩

大量流量下:

缓存层DB场景
存在存在正常(使用缓存)
不存在存在缓存击穿
不存在不存在缓存穿透
  • 击穿: 热key过期,导致大量流量打到db
  • 穿透: 大量请求缓存、DB不存在的数据,一般是恶意攻击;
  • 雪崩:大量的key过期,导致请求高峰,瞬间大量流量压到了DB;缓存层服务不在提供服务,所有请求流量压到了DB,导致DB无法对外正常提供服务,
    进而波及使用这个DB的相关系统,最终导致整个系统崩溃;

击穿

热key过期,导致请求高峰,瞬间大量流量压到了DB;

我们可以看到,击穿是因为key过期,或者冷启动热点数据没有加载进缓存。

解决方案:

  1. 热点key过期时间错峰,平滑过期
  2. 缓存预热,提前将一些数据加载到缓存,而不是用户请求的时候缓存中没有查库在写入缓存。
  3. 定时刷新值,在key过期前已经重新更新了键的值以及最新的过期时间

穿透

大量请求缓存、DB不存在的数据,一般是恶意攻击

从上面我们可以看到,正常用户的操作一般不可能产生穿透的场,极有可能是恶意攻击,

解决方案:

  1. 对不存在的key缓存默认值,防止同一key的大量请求被压到DB
  2. 对不存在的key加入到布隆过滤器,再次查询这个key的时候,
    缓存不存在判断是否在布隆过滤器中,在的话直接返回空值
  3. 对上面穿透请求的ip进行名单记录,进行限制

1. 默认空值

class Test {

    public String getValue(String key) {
        //1.缓存查key是否存在
        String value = redisService.get(key);
        if (StringUtils.isEmpty(value)) {
            //2. 查询db
            value = dbService.get(key);
            if (StringUtils.isEmpty(value)) {
                //3. 缓存默认值
                redisService.set(key, "1");
                return "1";
            }
        }
        return value;   
    }
}

2. 布隆

class Test {

    public String getValue(String key) {
        //1.缓存查key是否存在
        String value = redisService.get(key);
        if (StringUtils.isEmpty(value)) {
            //2. 缓存不存在,是否键在布隆中
            if(bollfilterContain(key)) {
                return "1";
            }
            //3.查db
             value = dbService.get(key);
        }
        return value;   
    }
}

上面的1,2结果方案还有漏洞,我们上面的代码只能抵挡同一key的大量请求,
如果攻击方每次都构造了不同的key来进行攻击呢?

这个时候,首先接口要有鉴权,根据攻击的手法一般的发起者会在他的几台几十台机器上进行自动化请求那么我们可以对同一ip进行限流;
如果攻击继续升级,攻击方调动了大量肉鸡,ip封不过来,怎么怎么办呢?
对这里的服务进行降级,部分可用。

雪崩

当大量的key同一时间过期,导致所有的请求都落到了数据库上;
单机redis挂掉,导致所有请求都落到了数据库上。

解决方案:

  1. redis使用集群(主从、sentinel哨兵)避免单机故障
  2. 设置热点key永不失效
  3. 设置key错峰过期,平滑过期
  4. 三级缓存使用缓存在应用或者memcache(用户请求——->redis—>应用hashmap\memcache---->db)
  5. 降级服务,保证服务不挂掉
缓存击穿缓存穿透缓存雪崩是与 Redis 缓存相关的常见问题。这些问题主要出现在缓存系统无法有效地处理某些请求或者在高并发情况下。 1. 缓存击穿:指的是一个热点数据突然失效,而此时有大量并发请求同一份失效的数据,导致这些请求穿透缓存,直接访问数据库,从而导致数据库压力过大。为了避免缓存击穿,可以在缓存失效的时候,设置短暂的锁来阻止其他请求直接访问数据库,并在锁过期后重新加载缓存。 2. 缓存穿透:指的是查询一个不存在的数据,而此类请求会直接绕过缓存,直接访问数据库。这样的请求会导致大量无效的数据库查询,造成数据库压力过大。为了避免缓存穿透,可以在查询结果为空时,也将空值保存到缓存中,并设置一个较短的过期时间。 3. 缓存雪崩:指的是大规模缓存失效,导致所有请求都直接访问数据库。这种情况通常是由于缓存服务器故障、过期时间设置不当或者缓存数据集中过度等原因引起的。为了避免缓存雪崩,可以设置缓存的过期时间时加上一个随机值,使缓存失效时间分散开来;或者使用多级缓存,将请求分散到不同的缓存服务器上。 以上是对于缓存击穿缓存穿透缓存雪崩的简要解释。在实际应用中,还可以结合具体的业务场景和实际需求采取一些其他的措施来防止这些问题的发生。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值