什么是缓存、为什么要用缓存、缓存分类、缓存测试、缓存更新、缓存设计考虑点、缓存测试点

一、缓存

缓存是一种将数据存储在高速缓存中的技术,它可以提高应用程序的性能和响应速度。

二、 为什么要用缓存

1. 高性能(主要目的)
查询耗时,但变化少,又有很多读请求情况下,可以将查询结果放到缓存中。减少对数据库的压力,提升响应速度。

在这里插入图片描述

2. 高并发
Mysql对高并发支持不好,单机撑到2kQPS容易告警,所以对于1s上万个请求,会让mysql宕机。缓存功能简单,说白了就是 key-value 式操作,单机支撑的并发量一秒可达几万十几万,单机承载并发量是 mysql 单机的几十倍。
在这里插入图片描述

三、缓存分类

本地缓存
定义:直接运行在应用程序本地的缓存组件
优点:应用程序和cache是在同一个进程内部,请求缓存非常快速,没有过多的网络开销等,在单应用不需要集群支持或者集群情况下各节点无需互相通知的场景下使用本地缓存较合适。
缺点:缓存跟应用程序耦合,多个应用程序无法直接的共享缓存,各应用或集群的各节点都需要维护自己的单独缓存,对内存是一种浪费。
在这里插入图片描述
分布式缓存
定义:分布式缓存是指独立的缓存服务,不和任何一个具体的应用耦合,可以独立运行并搭建缓存集群。类似数据库,所有的应用程序都可以连接同一个缓存服务以获取相同的缓存数据。
优点:自身就是一个独立的应用,与本地应用隔离,多个应用可直接的共享缓存。
缺点:优点也就是缺点,因为自身是一个独立的应用,本地节点都需要与其进行通信,导致依赖网络,同时如果缓存服务崩溃可能会影响所有依赖节点(缓存雪崩)。
在这里插入图片描述

四、缓存异常&测试方法

1.缓存雪崩
定义:大量缓存数据在同一时间过期(失效)或者 Redis 故障宕机。调用时这些接口查询缓存时无数据,去查询数据库,这些请求都指向数据库,数据库压力增大,耗时增加。
解决方案:

  • 均匀设置过期时间:避免同一时间失效
  • 读数据库加互斥锁:如果发现访问的数据不在 Redis 里,就加个互斥锁,保证同一时间内只有一个请求来构建缓存(从数据库读取数据,再将数据更新到 Redis 里),当缓存构建完成后,再释放锁。未能获取互斥锁的请求,要么等待锁释放后重新读取缓存,要么就返回空值或者默认值。
    实现互斥锁的时候,最好设置超时时间,不然第一个请求拿到了锁,然后这个请求发生了某种意外而一直阻塞,一直不释放锁,这时其他请求也一直拿不到锁,整个系统就会出现无响应的现象。
    后台更新缓存:不设置过期时间

模拟测试方法:对多个使用到缓存的接口进行并发调用,设置这些缓存时间已过期(即删除缓存),调用时这些接口查询缓存时无数据,去查询数据库,这些请求都指向数据库,数据库压力增大,耗时增加。

测试通过标准:每个缓存失效的数据都只执行了一次数据库查询并设置缓存,之后请求都命中了缓存。

2.缓存击穿
定义:热点数据过期,此时大量的请求访问了该热点数据,就无法从缓存中读取,直接访问数据库,数据库很容易就被高并发的请求冲垮。
解决方案

  • 设置热点数据永远不过期。
  • 读数据库时加互斥锁,写入缓存,其他等待线程就可以从缓存读取

模拟测试方法:对某个 Key 有大量的并发请求,这时从缓存中删除这个 key,再并发访问。
测试通过标准:并发调用接口,缓存失效的那个数据只有一个请求执行了数据库查询并设置缓存,其他查询则命中缓存。其他请求都命中了缓存。

3.缓存穿透
定义:不断发起查询缓存和数据库中都没有的数据,导致压力全部落在数据库,导致数据库压力过大。
解决方案:当数据库查询为空时,将缓存赋值默认值,后续查询都走缓存,减少数据库压力。
模拟测试方法:查询一个根本不存在的数据,缓存层和存储层都不会命中。
测试通过标准:每个不存在的数据都只执行了一次数据库查询并设置缓存,之后请求都命中了缓存,有效防止了缓存穿透问题。

五、 缓存更新方式

有三种更新方式:

  • 惰性加载(Lazy Loading/Expiration):这是最懒的更新方式。通过设置缓存有效期,让缓存失效后通过新的请求自动创建新的缓存。
    **优点:**实现简单,数据总是最新的,只有在数据被请求时才会更新,节省资源。
    缺点:在缓存失效后的第一个请求可能会遇到延迟,因为需要重新从数据源加载数据。此外,如果缓存中存储的是热点数据,可能会导致缓存击穿问题。
  • 缓存失效(Cache Invalidation):在更新db数据后,直接删除缓存,通过新的请求自动创建新的缓存。
    优点:简单直接,保证了下一次请求一定会得到最新数据。
    缺点:可能导致数据在缓存被删除和新缓存被创建之间的短暂时间内不一致。同时,如果删除操作和数据库更新操作之间有任何延迟,也会导致缓存和数据库之间的数据不一致。
  • 重新设置缓存(Write-Through/Update Cache):在更新db数据后,直接重新设置缓存。
    优点:缓存始终保持最新状态,避免了因缓存失效而导致的延迟,也减少了数据不一致的风险。
    缺点:每次数据库更新时都需要更新缓存,这可能会导致额外的开销,特别是在写操作频繁的场景下。

六、 缓存更新策略

1. 先删除缓存后更新数据库(会造成数据不一致)
在删除缓存未更新数据库前,有读请求更新缓存,从而导致数据库和缓存不一致。
在这里插入图片描述

2. Cache Aside(更新数据库后缓存失效)旁路换存储策略
最常用策略,应用程序直接与「数据库、缓存」交互,并负责对缓存的维护

  • 失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中。
  • 命中:应用程序从cache中取数据,取到后返回。
  • 更新:先把数据存到数据库中,成功后,再让缓存失效。
    在这里插入图片描述

也会发生数据不一致问题,但出现概率不高,原因是缓存的写入通常远快于比数据库写入。实际很难出现B更新完数据库删了缓存,A才更新完缓存清空。
在这里插入图片描述

如果业务对缓存命中率有严格的要求,那么可以考虑两种解决方案:

  • 一种做法是在更新数据时也更新缓存,只是在更新缓存前先加一个分布式锁,因为这样在同一时间只允许一个线程更新缓存,就不会产生并发问题了。当然这么做对于写入的性能会有一些影响;
  • 另一种做法同样也是在更新数据时更新缓存,只是给缓存加一个较短的过期时间,这样即使出现缓存不一致的情况,缓存的数据也会很快过期,对业务的影响也是可以接受。

3. Read/Write Through(读穿 / 写穿)策略
该模式把更新DB操作由Cache自己代理,对开发人员更简便。应用认为后端就是个单一存储,而存储自己维护自己的Cache。服务器只和 Cache 沟通,Cache 负责去沟通 DB,把数据持久化。
业界典型代表:Redis(可理解为 Redis 里包含了一个 Cache 和一个 DB)
在这里插入图片描述

Read Through 策略
先查询缓存中数据是否存在,如果存在则直接返回,如果不存在,则由缓存组件负责从数据库查询数据,并将结果写入到缓存组件,最后缓存组件将数据返回给应用。

Write Through 策略

  • 当有数据更新的时候,先查询要写入的数据在缓存中是否已经存在:如果缓存中数据已经存在,则更新缓存中的数据,并且由缓存组件同步更新到数据库中,然后缓存组件告知应用程序更新完成。
  • 如果缓存中数据不存在,直接更新数据库,然后返回;
    在这里插入图片描述

4. Write Behind Caching
Write Back(写回)策略在更新数据的时候,只更新缓存,同时将缓存数据设置为脏的,然后立马返回,并不会更新数据库。对于数据库的更新,会通过批量异步更新的方式进行。
优点

  • 让数据的I/O操作飞快(直接操作内存 )
  • 因为异步,write back还可合并对同一个数据的多次操作,对性能提高相当可观
    缺点
  • 数据非强一致性,可能丢失(Linux非正常关机会导致数据丢失)
  • 实现逻辑复杂,因为需track哪些数据是被更新的,待刷到DB
  • os的write back会在仅当该cache需失效时,才会被真正持久化,如内存不够或进程退出等情况,这又叫lazy write
    在这里插入图片描述

七、缓存设计考虑点

1.缓存时间设置合理性。
缓存时间设置,需要根据数据更新的频次合理设置;缓存时间太长会导致用户访问到的数据一直是老的,缓存设置时间太短对数据库访问会比较频繁。所以最好调研清楚实际数据更新的频次,再去设置缓存时间
2.存储逻辑合理性。
①服务端或数据库返回数据正确性。返回异常,不应该缓存;返回数据正常,才需要缓存;
②在缓存数据时,需要考虑查询条件的选择,这通常取决于业务需求和数据访问模式。例如,如果一个系统允许通过歌名或歌手来检索歌曲信息,那么可能需要为每种查询类型分别缓存数据。
3. 缓存读取逻辑合理性。以下是比较合理的逻辑:
有缓存,优先读取缓存;
无缓存,请求接口或查数据库获取数据;并存储缓存;
注意:缓存不命中也需要结合具体业务,比如上面的例子中,如果三位查不到缓存,大多数情况就是没有数据,在我们看来是一种正常的情况,会直接返回空结果,而不会去查数据库,避免造成缓存穿透。
4.缓存更新逻辑
缓存失效后是否会更新缓存的内容
注意:关注过期时间和更新时间的临界点,会不会出现异常情况,比如
5.缓存内容
redis缓存具体内容是否正确、格式(list、string)是否合理、实际每次缓存的数据数是否与需求一致
6.缓存数据重复
同样的数据触发保存缓存逻辑之后,应该只有一条在redis缓存中可以查到,重复缓存会浪费资源

八、缓存测试点

基本功能:

  1. 缓存增加:缓存与数据库的数据一致性检测。
  2. 缓存读取:缓存和数据库中均存在;缓存无,数据库有数据情况; 缓存和数据库中均不存在
  3. 缓存过期:验证数据在缓存中的过期机制是否按预期工作,包括时间过期和条件过期。再次请求,缓存是否正确写入。
  4. 缓存更新:当后端数据更新时,缓存应该相应地更新或失效。需要测试缓存更新机制是否正确执行。
  5. DB事务性导致回滚,缓存是否回滚,有没有产生脏数据。(可通过延迟写入解决)
  6. 缓存预热:验证缓存预热策略是否能够有效地将热点数据加载到缓存中,以避免系统启动初期的高延迟。

特殊场景

  1. 缓存读取时超时:校验缓存查询达到超时时间后,未返回指定的数据,对系统的影响。
    (可退化为查库)
  2. 缓存存储时超时:注意处理方式(比如重试)
  3. 特殊场景:缓存穿透、缓存雪崩、缓存击穿场景的解决方案
  4. 缓存上限:校验缓存淘汰参数配置与预期一致:增加缓存至达到 maxmemory 限制时(可修改 redis.conf 配置文件中配置的最大可用内存值),再次请求查询,数据返回正确,同时,检查被淘汰的数据确实是依照所配置的淘汰策略被移除的。
    监控线上的稳定性
  5. 监控缓存的命中率:评估缓存的设计是否达到预期;
  6. 监控中间件:CPU、内存是否异常;
  7. 监控是否有某个 key 过大;
  8. 监控是否存在缓存的频繁更新。

参考:https://mp.weixin.qq.com/s/9YXstvCin7pkmWlk4JI-fA
https://blog.csdn.net/qq_40685200/article/details/124861245

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/589947.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python实现【亚马逊商品】数据采集

前言 亚马逊公司,是美国最大的一家网络电子商务公司,位于华盛顿州的西雅图 是网络上最早开始经营电子商务的公司之一,亚马逊成立于1994年 今天教大家用Python批量采集亚马逊平台商品数据(完整代码放在文末) 地址&#…

应对服务器CPU占用持续性变高的解决办法

​  在服务器的使用过程中,高CPU使用率是一个常见的问题,一般是由于遇到大量流量,进程需要更多时间来执行或通过网络发送和接收大量网络数据包时,CPU使用率可能会急剧增加,严重时可能会影响到网络的性能和稳定性。因…

保护Word或Excel的几种方法,总有一种满足你的需求

你已经在Microsoft Word或Excel中创建了一个重要或机密文件,你希望将其保密或至少保持安全。也许你想确保只有你和某些人可以阅读或编辑它。也许你想限制某人可以对文件进行的修改类型。你甚至可以向读者保证这是最终版本。如果你知道在Word和Excel中使用哪些工具以及它们是如…

Git:常用命令(二)

查看提交历史 1 git log 撤消操作 任何时候,你都有可能需要撤消刚才所做的某些操作。接下来,我们会介绍一些基本的撤消操作相关的命令。请注意,有些操作并不总是可以撤消的,所以请务必谨慎小心,一旦失误&#xff0c…

提前应对威胁

通过新的《2023-2028 年荷兰国际网络安全战略》,荷兰政府在面对国家和犯罪分子持续构成的网络威胁时展现了责任和机构。它渴望将民主、人权和规范放在首位,并寻求维护全球开放、自由和安全的互联网。该战略明确了政府在国内实施打击的意愿和能力&#xf…

QT、C++实验室管理系统

一、需求介绍: 题目:基于Qt的实验室管理系统的设计 项目命名以LabSystem姓名拼音首字母(例如: LabSystemwXC) 功能要求: 一,基本必要功能: 1,使用QSQLITE数据库完成数据库的设计。 2,注册功能:包含学生注册&#xff0…

itvbox二开带会员如意版影视APP源码+视频搭建教程

详细教程V:shundazy1 网站环境必须为PHP 7.3 SQL5.6 如不是可能会出现软件打不开或者闪退情况。 首先创建网站,我这是内网,我就以IP加端口为例 上传源码到网站根目录 直接访问你的域名进行安装 访问域名 出现No input file specified.则关闭网站防跨…

【SpringBoot开发】之商城项目案例(实现登陆版)

🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是君易--鑨,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的博客专栏《SpringBoot开发之商城项目系列》。&#x1f3af…

msvcp140_1.dll丢失怎样修复,缺失msvcp140_1.dll是什么原因

在日常使用电脑的过程中,我们经常会遇到一些错误提示,其中之一就是“msvcp140_1.dll丢失”。那么,msvcp140_1.dll究竟是什么文件?为什么会出现丢失的情况?又该如何解决这个问题呢?本文将详细介绍msvcp140_1…

力扣-206. 反转链表

文章目录 力扣题目代码 力扣题目 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1] 示例 2: 输入:head [1,2] 输出&#x…

SQLSERVER排查CPU占用高

操作系统是Windows2008R2 ,数据库是SQL2008R2 64位 64G内存,16核CPU 硬件配置还是比较高的,他说服务器运行的是金蝶K3软件,数据库实例里有多个数据库 现象 他说是这几天才出现的,而且在每天的某一个时间段才会出现CPU占用高的情况 内存占用不太高,只占用了30个G CPU…

Android 跨进程之间通信(IPC)方式之ContentProvider

Android 跨进程之间通信 Android 跨进程之间通信(IPC)方式之BroadcastReceiverAndroid 跨进程之间通信(IPC)方式之ContentProvider 文章目录 Android 跨进程之间通信前言一、ContentProvider 是什么?二、如何利用ContentProvider跨进程通信1.创建自定义ContentProv…

关于发展模式加入变量的问题解决

问题1描述: 编译的时候不报错,但是在运行的时候出错输出 FLDLST: ustar in fincl( 17 ) not found ENDRUN: called without a message string 问题1解决: 这是因为在cas-esm 的atm_in 中写入了某个变量,但是在F90 代码里面没…

python使用动态规划解决不同路径问题

针对二维动态规划,还有一个问题就是关于求不同路径的实例,主要是说明在实际应用的场景中,要理解透彻实际问题的真正目的,就可以灵活实现代码编写。 对于求不同路径问题描述,对于一个机器人,处在一个mxn的网…

【Java 进阶篇】Maven 使用详解:打造便捷高效的项目构建利器

在软件开发的道路上,项目构建是一个不可避免的过程。而Maven,作为一个强大的项目管理和构建工具,为开发者提供了一套标准化的项目结构和构建流程。本文将围绕Maven的使用详解,手把手地带你探索Maven的世界,让你在项目构…

XTU-OJ-1452-完全平方数-笔记

参考博客 XTU-OJ 1452-完全平方数 题意 输入一个奇数&#xff0c;使得 n*(2*an-1)/2是一个完全平方数&#xff0c;求满足条件的最小的a 1<n<1e9 先输入样例数&#xff0c;再输入n 输入 2 1 3 输出 0 2 代码 #include<stdio.h>#define N 1000000010int a…

【UnityShader入门精要学习笔记】(1)了解渲染流水线

本系列为作者学习UnityShader入门精要而作的笔记&#xff0c;内容将包括&#xff1a; 书本中句子照抄 个人批注项目源码一堆新手会犯的错误潜在的太监断更&#xff0c;有始无终 总之适用于同样开始学习Shader的同学们进行有取舍的参考。 文章目录 渲染流水线什么是流水线什么…

【教3妹学编程-算法题】经营摩天轮的最大利润

3妹&#xff1a;“打个中国结&#xff0c;再系个红腰带&#xff0c; 愿善良的人们天天好运来, 你勤劳生活美, 你健康春常在, 你一生的忙碌为了笑逐颜开。” 2哥 : 3妹&#xff0c;元旦快乐啊。 3妹&#xff1a;2哥元旦快乐~。 2哥&#xff1a;祝新的一年&#xff0c;3妹技术突飞…

SPI通信

SPI通信 1、SPI通信概述 SPI(Serial peripheral interface)是一种同步、串行、全双工、总线制、主从工作方式。 有四线控制&#xff1a; SDO——主设备数据输出&#xff0c;从设备数据输入&#xff0c;对于MOSI output slave inputSDI——主设备数据输入&#xff0c;从事设备…

Linux之进程管理

什么是进程 在linux中每个执行的程序都称为一个进程&#xff0c;每个进程都分配一个ID号&#xff08;pid进程号&#xff09;。每个进程都可能以两种方式存在&#xff0c;即前台和后天。前台进程就是用户目前的屏幕上可以进行操作的。后台进程则是实际在操作&#xff0c;但屏幕…