Redis 缓存穿透 缓存击穿 缓存雪崩

Redis 缓存穿透 缓存击穿 缓存雪崩

缓存穿透

缓存穿透,字面理解,就是缓存形同虚设,请求直接穿过去了。
当查询缓存和数据库中都没有的数据时,就会产生这种情况。

举个栗子:如发起为id为“-1”的数据查询时,缓存和数据库都查不到结果,这时的用户很可能是攻击者,频繁攻击会导致数据库压力过大,直接挂掉。

那么该怎么解决呢?

  1. 接口层增加校验
    如用户鉴权校验,id做基础校验,id<=0的直接拦截。

  2. 缓存空数据,将数据库返回的null值进行缓存。
    从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击。

  3. 采用布隆过滤器进行拦截。
    将数据库中所有的查询条件,放入布隆过滤器中,
    当一个查询请求过来时,先经过布隆过滤器进行查,如果判断请求查询值存在,则继续查;如果判断请求查询不存在,直接丢弃。
    布隆过滤器显示结果存在,有一定概率它是不存在的,但是如果布隆过滤器的结果显示不存在,那么它一定不存在。

缓存击穿

缓存击穿就是在大量请求的情况下,某一个缓存数据突然失效(就好像是大量的请求把这个缓存数据给击穿了),导致大量的请求直接怼到DB上,把DB搞死了。

解决方案:

  1. 设置key永不过期
  2. 加互斥锁
//伪代码
public String get(key) {
    String value = redis.get(key);
    if (value == null) { //代表缓存值过期
        //设置3min的超时,防止del操作失败的时候,下次缓存过期一直不能load db
        if (redis.setnx(key_mutex, 1, 3 * 60) == 1) {  //代表设置成功
            value = db.get(key);
            redis.set(key, value, expire_secs);
            redis.del(key_mutex);
        } else {  //这个时候代表同时候的其他线程已经load db并回设到缓存了,这时候重试获取缓存值即可
            sleep(50);
            get(key);  //重试
        }
    } else {
        return value;      
    }
}

缓存雪崩

缓存雪崩和缓存击穿的区别就是缓存雪崩是大面积的key失效。

解决方案:

  1. 设置key永不过期
  2. 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值