0
点赞
收藏
分享

微信扫一扫

java基础巩固-宇宙第一AiYWM:为了维持生计,Redis基础Part5(四种类型缓存异常、四种解决异常的方案)~整起

J简文 2022-03-22 阅读 65
缓存redis

PART1:缓存异常,有四种类型

  • 缓存和数据库的数据不一致
    • 使用到缓存,无论是本地内存做缓存还是使用 Redis 做缓存,那么就会存在数据同步的问题,因为配置信息缓存在内存中,而内存是无法感知到数据在数据库的修改。这样就会造成数据库中的数据与缓存中数据不一致的问题
  • 缓存雪崩:缓存在某一个时刻出现大规模的key失效,那么就会导致大量的请求打在了数据库上面,导致数据库压力巨大,如果在高并发的情况下,可能瞬间就会导致数据库宕机这时候如果运维马上又重启数据库,马上又会有新的流量把数据库打死。这就是缓存雪崩
    • 造成缓存雪崩的关键在于同一时间的大规模的key失效,主要有两种可能:
      • 第一种是Redis宕机(缓存服务器某个节点宕机或者断网)
      • 第二种可能就是采用了相同的过期时间(某一个时间段内缓存集中过期失效)
    • 解决方案:
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
  • 缓存击穿:是某个热点的key失效,大并发集中对其进行请求,就会造成大量请求读缓存没读到数据,从而导致高并发访问数据库,引起数据库压力剧增。这种现象就叫做缓存击穿
    • 指的是一个key非常热点在不停着扛着大并发请求(相当于请求们大并发的集中对这一个点进行访问),当这个key在失效瞬间持续的大并发就击穿缓存并直接请求数据库,就相当于在屏障上凿开了一个洞,不就是击穿了吗
    • 解决方案:
      • 热点key不设置过期时间:不设置过期时间就不会出现热点key过期后产生的比如缓存击穿这种问题
        • 物理不过期,针对热点key不设置过期时间
        • 逻辑过期,把过期时间存在key对应的value里,如果发现要过期了,通过一个后台的异步线程进行缓存的构建
      • 降低打在数据库上的请求数量:加互斥锁:使用分布式锁保证对于每个key同时只有一个线程去查询后端服务,其他线程没有获得分布式锁 的权限因此只需要等待。(在缓存失效后,通过互斥锁或者队列来控制读数据写缓存的线程数量,比如某个key只允许一个线程查询数据和写缓存,其他线程等待。这种方式会阻塞其他的线程,此时系统的吞吐量会下降)----把压力转到了分布式锁
  • 缓存穿透(查不到某个数据导致的。(是指用户请求的数据在缓存中不存在即没有命中,同时在数据库中也不存在,导致用户每次请求该数据都要去数据库中查询一遍。如果有恶意攻击者不断请求系统中不存在的数据,会导致短时间大量请求落在数据库上,造成数据库压力过大,甚至导致数据库承受不住而宕机崩溃。))
    • 用户想要查询一个数据但发现redis内存数据库中没有(也就是说缓存没有命中),于是用户会再向持久层数据库查询发现也没有于是此次查询失败。当用户很多时缓存都没有命中,与是查询请求都去请求了持久层数据库,这就给持久层数据库造成很大压力,相当于出现了缓存穿透
    • 解决方案:
      在这里插入图片描述

PART2:共有四种解决异常的方案:

  • 先更新数据库,后更新缓存
    • 并发更新数据库场景下,会将脏数据刷到缓存。所以不能用
  • 先更新缓存,后更新数据库
    • 如果先更新缓存成功,但是数据库更新失败,则肯定会造成数据不一致,所以不能用
  • 先删除缓存,后更新数据库
    在这里插入图片描述
    在这里插入图片描述
  • 先更新数据库,后删除缓存
    • 这一种情况也会出现问题,比如更新数据库成功了,但是在删除缓存的阶段出错了没有删除成功,那么此时再读取缓存的时候每次都是错误的数据了
      在这里插入图片描述
举报

相关推荐

0 条评论