缓存击穿、穿透、雪崩

当请求比较多的时候,频繁地访问数据库会给数据库带来比较大的压力,所以此时我们会使用缓存作为缓解数据库压力的一种方式。

常见的缓存更新策略

  • Cache Aside(旁路缓存)策略

    • 当修改数据时,由应用程序来更新数据库,然后同时由应用程序来更新或者删除缓存
    • 低一致性需求:使用Redis的内存淘汰机制, 最多加上超时删除来兜底。
    • 高一致性需求:主动更新,并以超时删除作为兜底方案。
  • Read/Write Through(读穿/写穿)策略

    • Read/Write Through是应用程序只和缓存交互,不再和数据库交互。让缓存和数据库交互,相当于更新数据库的操作由缓存进行
      • Read Through: 查询缓存中数据不存在时,由缓存中间件负责从数据库查询数据,并将结果写入到缓存组件,最后缓存组件将数据返回给应用
      • Write Through: 当有数据更新的时候,先更新缓存中的数据,并且由缓存组件同步更新到数据库中,然后缓存组件告知应用程序更新完成
    • 常用的缓存中间件,如Redis,往往不提供这种方式。所以业务场景中不常用
  • Write Back(写回)策略

    • Write Back策略在更新数据的时候,只更新缓存,同时将缓存数据设置为脏的,然后立马返回,并不会更新数据库。之后会通过批量异步更新的方式来更新数据库
    • Write Back 策略特别适合写多的场景, 但是带来的问题是,数据不是强一致性的,而且会有数据丢失的风险
    • Write Back常用于计算机底层。比如 CPU 的缓存、操作系统中文件系统的缓存都采用了Write Back策略. 当电脑在突然断电之后,之前写入的文件会有部分丢失,就是因为 Page Cache 还没有来得及刷盘造成的.

我们的写业务代码时通常使用旁路缓存策略,有可能出现缓存击穿、穿透、雪崩问题。

缓存雪崩

所谓缓存雪崩,一般有两种情况。

  • 同一时间大量的key都过期了,导致访问这些key的大量请求访问数据库。
  • redis宕机了,导致大量请求访问数据库。

解决方案

  • 如果是大量key同一时间过期,则给key添加固定的过期时间的基础上, 再增加一个随机的过期时间。
  • 如果是Redis宕机, 那么就使用主从或者集群保证Redis高可用。
  • 最后,做好缓存雪崩的预防是一方面。另一方面,从服务保护的角度来说,要做好服务的限流,降级,熔断策略。即使万一发生了雪崩,也能让系统提供一定程度的服务,不至于整个宕机。

缓存穿透

缓存穿透: 请求的数据在数据库和缓存中都不存在, 那么请求就会直接访问数据库.

解决方案

  • 可以缓存空对象.
    • 优点是实现简单, 维护方便
    • 缺点是空对象会带来额外的内存消耗, 有可能出现短暂的数据不一致问题, 当每次请求的key都不一样时失效
  • 使用布隆过滤器。
    • 优点是不会有多余key, 内存占用少
    • 缺点是实现复杂, 且有误判的可能

缓存击穿

缓存击穿: 缓存击穿问题也叫热点Key问题,就是一个被大量请求访问的key突然失效了,大量请求打到了数据库上。

解决方案

  • 互斥锁: 如果redis中没查到数据, 缓存未命中. 则获取互斥锁(setnx), 获取失败则休眠重试, 获取成功则再次查询缓存是否存在(双重检测), 没查到则查询数据库进行缓存重建
    • 互斥锁注重一致性, 但是性能较差, 需要数据库与缓存强一致性选择互斥锁.
  • 逻辑过期: 缓存数据时不设置过去时间,需要在将要缓存的数据中加上时间属性作为逻辑过期时间. 当缓存命中则判断是否过期, 未过期直接返回数据, 过期则获取互斥锁. 获取锁失败则说明已经有人进行缓存重建了, 那么直接返回旧数据. 获取锁成功(需要双重检测)则开启新线程进行缓存重建, 原线程直接返回保证效率.
    • 逻辑过期性能好, 但是一致性差, 需要高性能选择逻辑过期.
相关推荐
Patrick_Wilson1 小时前
Go 为什么需要 defer?从函数怎么收尾说起
后端·go·编程语言
苏三说技术1 小时前
DeepSeek Harness入驻B站,评论区被干成了大型插件集市!
后端
橙序员小站2 小时前
我一句话让 AI 把公众号工作台搭完了:部署实测记录
后端
Patrick_Wilson2 小时前
从文本输出理解 Go 方法与接口
后端·go·编程语言
QCoding3 小时前
企业级Agent Evaluation实战:Agent能跑就能上线?AI Agent到底怎么测?
后端·spring
苍何3 小时前
让 WorkBuddy 操控浏览器,干活有点猛啊1
后端
IT_陈寒3 小时前
当Java的hashCode遇上Lombok,我的缓存被全清了
前端·人工智能·后端
XW3 小时前
常用提示词(Prompt)框架总结
后端
ServBay4 小时前
DeepSeek 再次崩了,DeepSeek V5正在路上?
后端·deepseek
IT规划师4 小时前
编程术语中的同步与异步:从"等不等"到工程取舍
后端·面试