4.如何避免缓存穿透、缓存击穿、缓存雪崩

先来看一下缓存穿透,是指业务请求穿过了缓存层,落到持久化存储上。在大多数场景下,我们应用缓存是为了承载前端业务请求,缓存被击穿以后,如果请求量比较大,则会导致数据库出现风险。

以双十一为例,由于各类促销活动的叠加,整体网站的访问量、商品曝光量会是平时的千倍甚至万倍。巨大的流量暴涨,单靠数据库是不能承载的,如果缓存不能很好的工作,可能会影响数据库的稳定性,继而直接影响整体服务。

那么哪些场景下会发生缓存穿透呢?

不合理的缓存失效策略

缓存失效策略如果设置不合理,比如设置了大量缓存在同一时间点失效,那么将导致大量缓存数据在同一时刻发生缓存穿透,业务请求直接打到持久化存储层。

外部用户的恶意攻击

缓存穿透如何在业务中避免呢?

  • 首先是设置合理的缓存失效策略,避免缓存数据在同一时间失效。
  • 缓存穿透还可以通过缓存空数据的方式避免。缓存空数据非常好理解,就是针对数据库不存在的数据,在查询为空时,添加一个对应 null 的值到缓存中,这样在下次请求时,可以通过缓存的结果判断数据库中是否存在,避免反复的请求数据库。不过这种方式,需要考虑空数据的 Key 在新增后的处理。
  • 缓存击穿也是缓存应用常见的问题场景,其是一个非常形象的表达。具体表现:前端请求大量的访问某个热点 Key,而这个热点 Key 在某个时刻恰好失效,导致请求全部落到数据库上。
  • 另外一个方案是使用布隆过滤器。布隆过滤器是应用非常广泛的一种数据结构,我们熟悉的 Bitmap,可以看作是一种特殊的布隆过滤器。使用布隆过滤器,可在缓存前添加一层过滤,布隆过滤器映射到缓存,在缓存中不存在的数据,会在布隆过滤器这一层拦截,从而保护缓存和数据库的安全。

在任何一组东西中,最重要的只占其中一小部分,约 20%,其余 80% 尽管是多数,却是次要的,因此又称二八定律。

二八定律在缓存应用中也不能避免,往往是 20% 的缓存数据,承担了 80% 或者更高的请求,剩下 80% 的缓存数据,仅仅承担了 20% 的访问流量。

由于二八定律的存在,缓存击穿虽然可能只是一小部分数据失效,但这部分数据如果恰好是热点数据,还是会对系统造成非常大的危险。

缓存击穿和缓存穿透都是降低了整体的缓存命中率,不过在表现上比较类似。缓存击穿可以认为是缓存穿透的一种特殊场景,所以在解决方案上也可以应用上面提到的那几种手段。

其是缓存穿透和缓存击穿升级的一种问题场景。

缓存雪崩的表现有两种,一种是大量的缓存数据在同一时刻失效,请求全部转发到数据库,将导致数据库压力过大,服务宕机;另外一种是缓存服务不稳定,比如负责缓存的 Redis 集群宕机。

在业务开发中,出现缓存雪崩非常危险,可能会直接导致大规模服务不可用,因为缓存失效时导致的雪崩,一方面是整体的数据存储链路,另一方面是服务调用链路,最终导致微服务整体的对外服务出现问题。

我们知道,微服务本身就存在雪崩效应,在电商场景中,如果商品服务不可用,最终可能会导致依赖的订单服务、购物车服务、用户浏览等级联出现故障。

你考虑一下,如果商品服务出现缓存雪崩,继而商品服务不可用,关联的周边服务都会受影响。

那么缓存雪崩在业务中如何避免呢?

首先是明确缓存集群的容量峰值,通过合理的限流和降级,防止大量请求直接拖垮缓存;其次是做好缓存集群的高可用,以 Redis 为例,可以通过部署 RedisCluster、Proxy 等不同的缓存集群,来实现缓存集群高可用。

首先明确应用缓存的目的,大部分缓存都是内存数据库,并且可以支持非常高的 QPS,所以缓存应用,可以防止海量业务请求击垮数据库,保护正常的服务运行。

其次,在考虑缓存的稳定性时,要从两个方面展开,第一个是缓存的数据,第二个是缓存容器也就是缓存服务本身的稳定性。

从缓存数据的层面,有一个缓存命中率的概念,是指落到缓存上的请求占整体请求总量的占比。缓存命中率在电商大促等场景中是一个非常关键的指标,我们要 尽可能地提高缓存数据的命中率,一般要求达到 90% 以上,如果是大促等场景,会要求 99% 以上的命中率

从缓存服务的层面,缓存集群本身也是一个服务,也会有集群部署,服务可用率,服务的最大容量等。 在应用缓存时,要对缓存服务进行压测,明确缓存的最大水位, 如果当前系统容量超过缓存阈值,就要通过其他的高可用手段来进行调整,比如服务限流,请求降级,使用消息队列等不同的方式。

所以我们在使用缓存的时候,要把这几个场景都考虑到,做到在使用缓存的时候,保持稳定状态。

Original: https://www.cnblogs.com/daohangtaiqian/p/16534965.html
Author: 道行太浅
Title: 4.如何避免缓存穿透、缓存击穿、缓存雪崩

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/594402/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 在k8s中导出jvm内存错误dump文件到OSS

    加参数 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=logs/test.dump 可以实现在 jvm发生内存错误后 会生成du…

    Java 2023年6月16日
    079
  • Nginx配置http https正向代理

    1.编译安装nginx,需要安装第三方模块ngx_http_proxy_connect_module #安装依赖 yum -y install patch unzip gcc gc…

    Java 2023年5月30日
    097
  • nginx 配置其他路径

    gedit /etc/nginx/sites-enabled/default location /hlstest {types {application/vnd.apple.mpe…

    Java 2023年5月30日
    071
  • Java基础之Synchronized原理

    思维导图svg: https://note.youdao.com/ynoteshare1/index.html?id=eb05fdceddd07759b8b82c5b9094021…

    Java 2023年5月29日
    083
  • SpringMVC&Maven进阶

    SpringMVC 3.1 了解SpringMVC 概述 SpringMVC技术与Servlet技术功能等同,均属于web层开发技术 学习路线 请求与响应 REST分割 SSM整合…

    Java 2023年6月6日
    096
  • Spring 中的事件机制 ApplicationEventPublisher

    当用户注册后,给他发送一封邮件通知他注册成功了,然后给他初始化积分,再发放一张新用户注册优惠券等。 用户注册事件 用户注册服务发布者 注意:再Spring中,服务必须交给 Spri…

    Java 2023年5月30日
    069
  • 面向对象设计六大原则

    六大设计原则主要是指: 单一职责原则(Single Responsibility Principle); 开闭原则(Open Closed Principle); 里氏替换原则(L…

    Java 2023年6月9日
    078
  • 如何解决高并发和大流量

    简介: 名词解释:并发 在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任意一个时刻上只有一个程序在处理机上运行。 …

    Java 2023年6月7日
    081
  • Java实现抽奖模块的相关分享

    最近进行的项目中,有个抽奖的需求,今天就把相关代码给大家分享一下。 一、DAO层 /** * 获取奖&#x…

    Java 2023年6月15日
    0117
  • MVC三层架构

    MVC三层架构 什么是MVC:model view controller 模型、视图、控制器 大致框架: Model 业务处理:业务逻辑(service) 数据持久层:CRUD(D…

    Java 2023年6月13日
    070
  • 461. Hamming Distance

    The Hamming distance between two integers is the number of positions at which the correspo…

    Java 2023年6月15日
    082
  • 如何使用Arthas定位问题

    在我们日常的工作中,经常会遇到一些线上才会遇到的问题。Arthas无疑是我们在工作中,定位线上问题的神奇。下面,我将介绍一下我们在工作中经常用到的一些功能。 dashboard 首…

    Java 2023年6月7日
    070
  • phpshe xml注入

    php商城系统 xml注入 页面样式 Xml原理参考: https://www.cnblogs.com/20175211lyz/p/11413335.html 漏洞函数simple…

    Java 2023年6月6日
    082
  • 【译】Spring的@EnableCaching注解

    Spring的@EnableCaching注解 @EnableCaching注解是spring framework中的注解驱动的缓存管理功能。自spring版本3.1起加入了该注解…

    Java 2023年5月29日
    0150
  • HIT软构博客5–LAB2记录与总结

    本次实验我学习了ADT的设计、规约、测试,并使用OOP技术实现 ADT。 ​ 首先按照给定的需求,从中根据名词找到对应需要设计的ADT,然后确定ADT内所需要的方法,设计方法的sp…

    Java 2023年6月5日
    094
  • SpringBoot集成文件-如何使用POI导出Word文档?

    前文我们介绍了通过Apache POI导出excel,而Apache POI包含是操作Office Open XML(OOXML)标准和微软的OLE 2复合文档格式(OLE2)的J…

    Java 2023年6月6日
    0103
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球