首页 > 其他分享 >学习笔记—缓存穿透、缓存雪崩、缓存击穿

学习笔记—缓存穿透、缓存雪崩、缓存击穿

时间:2023-12-07 17:11:06浏览次数:34  
标签:缓存 Key 过期 数据库 击穿 雪崩 key 请求

缓存穿透

  • 定义:缓存穿透指的查询缓存和数据库(缓存找不到就会在数据库找)中都不存在的数据,这样每次请求直接打到数据库,就好像缓存不存在一样。
    • 例:“当查询数据库时如果没有查询到数据,则直接返回Null给前端用户,流程结束”,如果前端频繁发起访问请求时,恶意提供数据库中不存在的Key,则此时数据库中查询到的数据将永远为Null。由于Null的数据是不存入缓存中的,因而每次访问请求都会查询数据库。如果此时有恶意攻击,发起“洪流”式的查询,则很有可能会对数据库造成极大的压力,甚至压垮数据库。
  • 缓存穿透可能会使后端存储负载加大,如果发现大量存储层空命中,可能就是出现了缓存穿透问题。
  • 解决方法
    1. 缓存空值:在数据库不命中之后,把这个Key值保存进Redis,值设为空对象或者默认值,当下次再通过这个Key查询时就不需要再查询数据库。
      1. 问题:空值做了缓存,意味着缓存层中存了更多的键,需要更多的内存空间。解决方法:设置一个过期时间
      2. 问题:假如传进来的这个不存在的Key值每次都是随机的,那存进Redis也没有意义。
    2. 使用布隆过滤器,可以在缓存之前再加一层布隆过滤器,在查询的时候先去布隆过滤器查询 key 是否存在,如果不存在就直接返回。
      1. 步骤:
        1. 第一次初始化的时候,会把数据库中所有已存在的key,经过一些列的hash算法(比如:三次hash算法)计算,每个key都会计算出多个位置,然后把这些位置上的元素值设置成1。
        2. 当有用户key请求过来的时候,再用相同的hash算法计算位置。如果多个位置中的元素值都是1,则说明该key在数据库中已存在。这时允许继续往后面操作。如果有1个以上的位置上的元素值是0,则说明该key在数据库中不存在。这时可以拒绝该请求,而直接返回。
      2. 问题:
        1. 存在误判的情况。但通常情况下,布隆过滤器的误判率还是比较少的。即使有少部分误判的请求,直接访问了数据库,如果访问量并不大,对数据库影响也不大。
          • 解决方法:可以适当增加hash函数
        2. 存在数据更新问题。如果数据库中的数据更新了,需要同步更新布隆过滤器。但它跟数据库是两个数据源,就可能存在数据不一致的情况。

缓存击穿

  • 定义:缓存中某个频繁被访问的Key(可以称为“热点Key”),在不停地扛着前端的高并发请求,当这个Key突然在某个瞬间过期失效时,持续的高并发访问请求就“穿破”缓存,直接请求数据库,导致数据库压力在某一瞬间暴增。这种现象就像是“在一张薄膜上凿出了一个洞”。
  • 例:很多用户同时购买一个商品,这个商品本来是放在缓存里面,突然某个时刻这个商品的缓存过期了,但是这个时候还有很多用户在购买这个商品,这个时候这些用户的请求就还打在数据库上,一下子数据库的压力过大,就可能直接挂掉。
  • 解决方法:
    • 加锁:如上例中,查询缓存,发现缓存中不存在,加锁,让其它线程等待,只让一个线程去更新缓存。
    • 缓存不失效:如上例中,大量用户抢购一个商品,就相当于一个热门商品的秒杀活动,可以不用设置过期时间,让其永久有效的。然后,在秒杀活动开始前,我们先用一个程序提前从数据库中查询出商品的数据,然后同步到缓存中,提前做预热。等秒杀活动结束一段时间之后,我们再手动删除这些无用的缓存即可。

缓存雪崩

  • 定义:当某一个时刻出现大规模的缓存失效的情况 (例如缓存服务宕机、大量key在同一时间过期) ,那么就会导致大量的请求直接打在数据库上面,导致数据库压力巨大,如果在高并发的情况下,可能瞬间就会导致数据库宕机。这时候如果运维马上又重启数据库,马上又会有新的流量把数据库打死。这就是缓存雪崩。
  • 分析:这种问题产生的原因其实主要是因为大量的Key在某个时间点或者某个时间段过期失效导致的。
  • 解决方法:
    • 过期时间:为这些Key设置不同的、随机的TTL(过期失效时间),从而错开缓存中Key的失效时间点,可以在某种程度上减少数据库的查询压力。而热点数据可以设置永不过期
    • 提高缓存可用性:集群部署、多级缓存
    • 熔断降级:
      • 服务熔断
      • 服务降级:当出现大量缓存失效,而且处在高并发高负荷的情况下,在业务系统内部暂时舍弃对一些非核心的接口和数据的请求,而直接返回一个提前准备好的 fallback(退路)错误处理信息。

分析总结

  • 不管是缓存穿透、缓存雪崩还是缓存击穿,最终的后果都是给DB(数据库)造成压力,甚至压垮数据库。那么它们的解决方案也都有一个共性,那就是“加强防线”,尽量让高并发的读请求落在缓存中,从而避免打到数据库。
  • 缓存雪崩可以说是缓存击穿的升级版,缓存击穿只是一个热门的key突然失效,而缓存雪崩是多个热门的key同时失效。

参考:
[1] 分布式中间件技术实战-java版- 钟林森
[2] https://cloud.tencent.com/developer/article/2046488

标签:缓存,Key,过期,数据库,击穿,雪崩,key,请求
From: https://www.cnblogs.com/qq286442936/p/17883403.html

相关文章

  • Spring Boot 3.2项目中使用缓存Cache的正确姿势!!!
    你是否曾想过为什么在SpringBoot应用中缓存是如此重要?答案在于它通过减少数据检索时间来提高性能。在本文中,我们将深入探讨缓存对微服务模式的影响,并探讨根据操作易用性、速度、可用性和可观测性等因素选择正确缓存的重要性。我们还将探讨如何最大程度地提高缓存性能和可用性。......
  • 【项目学习】谷粒商城学习记录4 - 高级篇(性能压测 & 缓存)
    【项目学习】谷粒商城学习记录4-高级篇(性能压测&缓存)一、性能压测1、Jmeter(1)Jmeter安装jmeter官网download页选择支持java8+的.zip版本下载,解压后打开bin/jemter.bat,并修改语言2、Nginx动静分离为什么要动静分离?未分离的项目静态资源放在后端,无论是动......
  • Spring Boot 3.2项目中使用缓存Cache的正确姿势!!!
    你是否曾想过为什么在SpringBoot应用中缓存是如此重要?答案在于它通过减少数据检索时间来提高性能。在本文中,我们将深入探讨缓存对微服务模式的影响,并探讨根据操作易用性、速度、可用性和可观测性等因素选择正确缓存的重要性。我们还将探讨如何最大程度地提高缓存性能和可用性。......
  • 基于社区电商的Redis缓存架构-库存模块缓存架构(下)
    基于缓存分片的下单库存扣减方案将商品进行数据分片,并将分片分散存储在各个Redis节点中,那么如何计算每次操作商品的库存是去操作哪一个Redis节点呢?我们对商品库存进行了分片存储,那么当扣减库存的时候,操作哪一个Redis节点呢?通过轮询的方式选择Redis节点,在Redis中通过记录......
  • 深入探讨Guava的缓存机制
    第1章:引言大家好,我是小黑,今天咱们聊聊GoogleGuava的缓存机制。缓存在现代编程中的作用非常大,它能提高应用性能,减少数据库压力,简直就是性能优化的利器。而Guava提供的缓存功能,不仅强大而且使用起来非常灵活。在咱们深入挖掘之前,先简单说说缓存。缓存,其实就是一种保存数据的手段......
  • 100MB缓存新神U!AMD锐龙7 5700X3D蓄势待发
    AMD将在2024年第一季度发布新款锐龙75700X3D,这也将是3D缓存家族最便宜的零售型号。锐龙75800X3D作为首款3D缓存处理器,一炮打响,成为主流游戏玩家的最佳选择。Zen4时代,AMD一口气推出了锐龙97950X3D/7900X3D、锐龙77800X3D,但定位和价格都更高了。AMD虽然后来增加了锐龙55600X......
  • Nginx缓存入门实战(01)-深入实践ETag机制
    1RFC7232指纹1.1响应头部ETag=entity-tag,仅对同一个URL下的比较有意义。为啥需要这玩意?因为HTTP协议本质就是个KV,K=URL,V=body。因为URL并没有变,但我的V是会变的!所以需要对V生成一个摘要!1.2请求头部If-Match="*"/1#entity-tag。用于并发修改资源(POST/PUT/......
  • 缓存
     1.网页端(浏览器)缓存: 适用用户只查询自己的信息接口,一个浏览完为一个缓存。直接在Get接口上增加[ResponseCache(Duration=5)],5为缓存时间,单位:S。 2.服务器缓存:适用公共接口不带参数查询。接口上增加[ResponseCache(Duration=5)],builder.Services.AddResponseCaching();......
  • Redis缓存和MySQL数据一致性方案详解
    需求起因在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节。所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库读取缓存步骤一般没有什么问题,但是一旦涉及到数据更新:数据库和缓存更新,就容易出现缓存(Redis)和数据库(MYSQL)间......
  • 基于社区电商的Redis缓存架构-写多读多场景下的购物车缓存架构
    社区电商的购物车缓存架构在购物车中的功能主要有这几个:商品加入购物车、查看购物车列表、删除购物车商品、选中购物车商品进行结算这里购物车的场景和之前用户信息以及菜谱分享信息还不同,如果在举办了大型购物活动时,购物车可能需要面临写多读少或者写多读多的场景,面临高并发的读和......