redis缓存问题

72 阅读2分钟

缓存穿透

大量用户查询数据库没有的数据,导致数据库长时间处于被大量访问的状态

  1. 将这些请求的数据存储到redis里,过期时间设置短点,避免大量的空对象占据过多的空间
  2. 在微服务网关或拦截器中设置逻辑监控,限制IP对同一数据的访问量,防止通过缓存穿透进行的恶意攻击
  3. 使用布隆过滤器(Bloom Filter)进行拦截

布隆过滤器资料布隆(Bloom Filter)过滤器——全面讲解,建议收藏_李子捌的博客-CSDN博客

缓存击穿

指要查询的数据在缓存中没有,要到数据库里找,但同一时间有大量用户查询这个数据,导致数据库压力飙升

处理方案:

  1. 缓存预热:

    1. 将长期不会发生变动且经常被查询的数据,设置永不过期。
    2. 将会处于热点的数据,延长过期时间至热度下降的时间,如新发布的活动。
  2. 限流降级:缓存击穿就是同一时间有大量的用户进行访问同一数据,只要在访问时缓存不存在就进行上锁,限制对数据库的访问量,当从数据库获取数据后,存储到缓存里再释放锁。

public String getData(String key) throws InterruptedException {
​
    // 首先从缓存读取数据
    String val = getDataFromRedis(key);
​
    // 如果缓存不存在则去数据库获取
    if (val == null) {
        // 获取锁
        if (lock.tryLock()) {
​
            // 从数据库获取数据
            val = getDataFromDB(key);
​
            if (val != null) {
                setCache(key, val);
            }
            
            // 释放锁
            lock.unlock();
        } else {
            // 其他线程获取锁失败,睡眠100毫秒后尝试重新获取
            Thread.sleep(100);
            val = getData(key);
        }
    } 
    return val;
}

缓存雪崩

大量缓存同时失效

  1. 尽量避免缓存过期时间设置在同一时间
  2. 多增设几台redis,避免一台redis挂掉导致出现的缓存雪崩
  3. 与缓存击穿的缓存预热和限流降级一样,减少缓存失效时对数据的压力