后端工程师的高阶面经
邓明
前 Shopee 高级工程师,Beego PMC
6888 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 50 讲
后端工程师的高阶面经
15
15
1.0x
00:00/00:00
登录|注册

35|缓存问题:怎么解决缓存穿透、击穿和雪崩问题?

你好,我是大明。今天我们再来聊一个缓存中的热门面试话题:怎么解决缓存穿透、击穿和雪崩问题。
这个问题之所以常见,是因为你在使用缓存的过程中一不小心就会遇到它们。比如说在前面的课程里面我给你讲过,如果缓存崩溃,那么大量请求就会落到数据库上,直接把数据库压垮。然而很多新手在刚接触缓存的时候完全意识不到这个问题,只有在出了线上故障之后才会考虑缓存崩溃的事情。因此,面试官就倾向于在面试的时候确认你是否会解决这一类的问题。
这一节课,我就带你综合分析这三种情况,以及其他可能出现的缓存问题。
不得不说的是,缓存穿透、击穿和雪崩是三个很容易搞混的概念,尤其是缓存穿透和击穿。

缓存穿透

缓存穿透是指数据既不在缓存中,也不在数据库中
最常见的场景就是有攻击者伪造了大量的请求,请求某个不存在的数据。这会造成两个后果。
缓存里面没有对应的数据,所以查询会落到数据库上。
数据库也没有数据,所以没有办法回写缓存,下一次请求同样的数据,请求还是会落到数据库上。
如果你没有在服务层面上采用熔断、限流之类的措施,那么数据库就可能崩溃。

缓存击穿

缓存击穿是指数据不在缓存中,导致请求落到了数据库上。注意,数据这个时候在数据库中是存在的,所以我们可以预计,查询到数据库中的数据之后就会回写缓存。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了缓存穿透、击穿和雪崩问题,并提供了解决方案。对于缓存穿透,作者建议采用回写特殊值和使用布隆过滤器的方法来解决。而对于缓存击穿问题,建议采用singleflight模式。针对缓存雪崩问题,作者提出了合理设置缓存过期时间和采用多级缓存的解决方案。此外,文章还提到了限流的作用,以及集群互为备份的亮点方案。这些解决方案对读者在面对实际问题和面试准备中都具有一定的参考价值。文章内容丰富,涵盖了缓存问题的多个方面,为读者提供了全面的技术指导。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《后端工程师的高阶面经》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(7)

  • 最新
  • 精选
  • 黑客不够黑
    亮点方案中跨云厂商使用redis是不是欠妥?考虑过网络延迟吗?使用缓存一般都在局域网内,夸厂商,极端情况跨地域,如果不上专线,网络延迟可能还不如查数据库来的快;中间件、数据库这些基础设施不应公网访问,就算夸机房也会拉专线保证低延迟

    作者回复: 使用 Redis 有些时候不仅仅是为了查询性能,还是为了保护数据库。也就是说即便你考虑到跨网络跨地域查询很快,但是只要是查询 Redis,数据库就不会被查询压垮。

    2024-02-27归属地:江苏
  • nadream
    需要专门维护布隆过滤器吗?每次有数据新增了,都要往布隆过滤器中写入呢

    作者回复: 是的。如果不想同步维护,你借助 Canal 之类的也可以,就是会产生更多的假阳性。 部分失败也不要紧,因为撑死了就是到了唯一索引那里。

    2024-01-26归属地:浙江
  • Geek_3d0fe8
    那个备份集群数据如果不同步的话,直接切过去不会有问题吗

    作者回复: 没啥太大的问题,就是一瞬间缓存上都没数据,都会落到数据库上。你做好数据库上的保护工作就可以了。等后续缓存重建起来就可以了。

    2023-12-13归属地:广东
  • seckiller
    有Java版本的singleflight实现吗

    作者回复: 我还真没用过,但是开源的是有的,你在 github 上线随便搜索就能找到。

    2023-10-09归属地:上海
    2
  • 波多黎各仔
    请教下老师,在真实的场景下,真的会采取上述说的几个基本解决方案吗?我是感觉做好限流就好了啊,比如说,缓存穿透的解决方案是给个默认值,但是攻击者可以找个没有缓存的接口来攻击,那样就没辙了。

    作者回复: 如果你的服务本身,不存在数据库查询扩散的问题,那么服务直接限流就可以了。也就是说,调用你的服务一次,只会读缓存一次。那么有一些批量接口是不满足这个条件的。当然这也是有前提条件的,就是你的数据库在正常流量全部缓存未命中的时候,能够撑住。但是高并发服务也是不满足这个前提的。 正常来说,我至少会利用 ORM 来搞个限流,直接基于本地内存的限流就够了。只有在一些很罕见的场景我才会用更加复杂的方案。毕竟我也是一个懒人,不出 BUG 谁去管。

    2023-09-13归属地:江苏
  • Johar
    老师,redis集群一般都是cluster或者sentinel方式部署,主节点故障,自动切换到从节点就行,你说的是不是机房故障?

    作者回复: 对,整个不可用!

    2023-09-08归属地:重庆
  • peter
    请教老师几个问题: Q1:Java对布隆过滤器有缺省实现吗?拿来就用的那种。 Q2:MySQL一般能承受多大的QPS? Q3:系统在设计的时候,需要考虑黑客攻击吗?比如我准备开发一个网站,除了考虑正常并发以外,还需要考虑黑客攻击的流量吗?

    作者回复: 1. 直接调用 Redis API 就可以,低版本 Redis 就得自己手写了; 2. 这个看你的机器性能 3. 需要,一般都需要。你要相信互联网每一个人都不怀好意。

    2023-09-08归属地:河南
    2
收起评论
显示
设置
留言
7
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部