用了强大的 Redis,咱们的项目是否是再也不害怕高并发查询了?缓存穿透和缓存雪崩了解一下

关于 Redis 的使用,你们应该已经不陌生了,我也介绍过 Redis 的使用、数据结构、使用场景分析,既然 Redis 这个强大,那么架构中引入了 Redis 以后,是否是就“无敌”了呢?数据库

其实全部的架构、框架、组件,在解决一部分问题的同时,一样也会带来新的问题,让咱们看看使用 Redis 可能会遇到什么样的问题。缓存

缓存穿透

Redis 大部分的使用场景,都是根据 key ,先在 Redis 中查询,若是查询不到的话,再查询数据库。数据结构

当有大量的请求,key 值根本不在 Redis 中,那么查询就会落到数据库上,这些请求就仿佛“穿透”过了 Redis 落在了数据库上,最后会致使数据库不堪重负直至崩溃。架构

缓存穿透

让咱们看看缓存穿透的应对策略:框架

1. 将无效 key 保存到 Redis 中

若是 Redis 中查询不到,而且查询数据库也没有结果,那么就将这个 key 写入到 Redis 中,设置 value = 空,这样若是这个 key 值被重复访问,也不会查询数据库。工具

将无效 key 保存到 Redis 中

可是若是数据库几分钟后,存入了一条真实的数据,那么就会发生数据库和缓存数据不一致的状况;spa

这种状况,要么主动更新 Redis 中这条 key-空 的数据,要么在设置缓存的时候,同时设置缓存的额过时时间,这样当时间一过,缓存数据就能够刷入到 Redis 中了。插件

若是每次查询的 key 值都不相同,好比收到恶意攻击,每次访问都是无效且不相同的 key 值,那么这个办法就会失效。线程

2. 布隆过滤器

布隆过滤器(Bloom Filter)的原理解释起来很复杂,用白话归纳一下它的特色:它说某个 key 不存在,那么就必定不存在,它说某个 key 存在,那么很大多是存在(存在必定的误判率)。code

使用布隆过滤器,挡回无效请求,流程大概是这样的:

布隆过滤器

对布隆过滤器感兴趣的同窗,能够试一试 Google 出品的 Guava 工具库,其中就有开箱即用的布隆过滤器:BloomFilter;

public class BloomFilterTest {
    public static void main(String[] args){
        int size = 1000000;
        //布隆过滤器
        BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, 0.001);
        
        for (int i = 0; i < size; i++) {
            bloomFilter.put(i);
        }
        
    List<Integer> list = new ArrayList<Integer>(1000);
        for (int i = size + 1; i < size + 10000; i++) {
            if (bloomFilter.mightContain(i)) {
                list.add(i);
            }
        }
        System.out.println("误判数量:" + list.size());
    }
}

另外,Redis 在 4.0 以后有了插件功能(Module),可使用外部的扩展功能,可使用 RedisBloom 做为 Redis 布隆过滤器插件。

缓存雪崩

一般咱们在使用 Redis 的时候,都会为缓存设置过时时间,可是若是在某个时间点,有大量缓存失效,那么下一个时间点就会有大量请求访问到数据库,这种状况下,数据库可能由于访问量多大致使“崩溃”,这就是缓存雪崩。

让咱们看看缓存雪崩的解决方案:

1. 不设置缓存过时时间

最暴力的解决办法,缓存不设置自动过时时间,只要缓存不崩,数据库就不会崩。

2. 设置随机过时时间

另一个办法,就是让缓存过时时间不那么一致,好比一批缓存数据24小时后过时,那么就在这个基础上,让每条缓存的过时时间先后随机 1-6000 秒(1-10分钟)。

3. 使用互斥锁

在缓存失效后,经过互斥锁或者队列,控制读数据库和写缓存的线程数量;不过这样会致使系统的吞吐量降低。

4. 双缓存

设置一级缓存和二级缓存,一级缓存过时时间短,二级缓存过时时间长或者不过时,一级缓存失效后访问二级缓存,同时刷新一级缓存。

最后在强调一遍,任何架构、组件、框架的引入,都会带来新的问题,咱们在使用的时候必定要有相应的评估和解决方案。

会点代码的大叔 | 文【原创】

敬请关注会点代码的大叔

相关文章
相关标签/搜索