美文网首页程序员
阿里面试官带你一步步理解面试常问的缓存击穿、缓存穿透和缓存雪崩

阿里面试官带你一步步理解面试常问的缓存击穿、缓存穿透和缓存雪崩

作者: 来壹杯卡布奇诺 | 来源:发表于2020-04-30 13:19 被阅读0次

    一、前言

    对于使用过Redis的同学,一定听过缓存击穿、缓存穿透或者缓存雪崩吧?这是缓存系统最常见的几个问题。 但是我相信很多同学对这三个之间的概念都是模模糊糊的,今天这篇文章就是为了说明这三者之间的区别,以及如果解决这些问题。希望你在面试相关问题时可以准确的回答。

    二、缓存穿透

    一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。如果key对应的value是一定不存在的,并且对该key并发请求量很大,就会对后端系统造成很大的压力。

    也就是说,对不存在的key进行高并发访问,导致数据库压力瞬间增大,这就叫做【缓存穿透】

    解决方案:对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了之后清理缓存。

    三、缓存雪崩

    当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。

    突然间大量的key失效了或redis重启,大量访问数据库而导致的系统压力剧增问题就是缓存雪崩啦

    解决方案:

    1. key的失效期分散开,不同的key设置不同的有效期;
    2. 设置二级缓存;
    3. 高可用方案,比如redis集群,保证不会因为缓存系统崩溃而导致缓存雪崩;

    四、缓存击穿

    对于一些设置了过期时间的key,如果这些key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。这个时候,需要考虑一个问题:缓存被“击穿”的问题,这个和缓存雪崩的区别在于这里针对某一key缓存,前者则是很多key。

    缓存在某个时间点过期的时候,恰好在这个时间点对这个Key有大量的并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。

    解决方案:用分布式锁控制访问的线程,如:使用redis的setnx互斥锁先进行判断,这样其他线程就处于等待状态,保证不会有大并发操作去操作数据库。

    if(redis.sexnx()==1){ //先查询缓存 //查询数据库 //加入缓存 }
    

    五、缓存双写一致性

    这个问题是业务开发中常见的问题,那就是在写redis和数据库时如何保证数据的一致性呢? 如果你还不了解什么情况下会出现双写一致性问题,那么下面我来举几个例子,大家看看是不是很熟悉?你们平常是不是就是这么来使用redis的呢?

    先更新数据库再更新缓存(不建议使用)

    操作步骤(线程A和线程B都对同一数据进行更新操作):

    线程A更新了数据库
    线程B更新了数据库
    线程B更新了缓存
    线程A更新了缓存
    

    显而易见,这面这种操作的问题在于:脏读、浪费性能

    先更新数据库再删除缓存

    操作步骤

    请求A进行写操作,删除缓存,此时A的写操作还没有执行完
    请求B查询发现缓存不存在
    请求B去数据库查询得到旧值
    请求B将旧值写入缓存
    请求A将新值写入数据库
    

    此方案,可以看到在步骤4会将旧值最后写入缓存,最终造成脏读;

    先删除缓存再更新数据库

    操作步骤

    用户A删除缓存失败
    用户A成功更新了数据
    

    或者

    用户A删除了缓存;
    用户B读取缓存,缓存不存在;
    用户B从数据库拿到旧数据;
    用户B更新了缓存;
    用户A更新了数据;
    

    按照上面的步骤,此方案也是会出现脏读问题,导致数据双写不一致而引发业务系统异常。

    这里给出几种解决方案:

    • 解决方案1:设置缓存有效时间(最简单),在接受最终一致性的场景下,配置合理的失效时间。
    • 解决方案2:使用消息队列,例如rocketMq等消息队列可以保证数据操作顺序一致性,确保缓存系统的数据正常。

    这就是Redis缓存系统经常问的 缓存击穿、缓存雪崩、缓存击穿 之间的区别,虽然这几个概念听着非常的相似,实质上在定义上还是有一些细微的区别。同时也介绍了在业务系统使用中常见的 数据双写缓存一致性 问题的场景和推荐的解决方案,希望能帮助到大家。

    相关文章

      网友评论

        本文标题:阿里面试官带你一步步理解面试常问的缓存击穿、缓存穿透和缓存雪崩

        本文链接:https://www.haomeiwen.com/subject/goezwhtx.html