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

news2024/11/25 11:29:20

一、缓存

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

二、 为什么要用缓存

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.coloradmin.cn/o/1350106.html

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

相关文章

光伏、储能一体化监控及运维解决方案 安科瑞 许敏

前言:今年以来,在政策利好推动下光伏、风力发电、电化学储能及抽水蓄能等新能源行业发展迅速,装机容量均大幅度增长,新能源发电已经成为新型电力系统重要的组成部分,同时这也导致新型电力系统比传统的电力系统更为复杂…

clang-format

Clang-Format Clang-Format Style Options — Clang 18.0.0git documentation VSCode 1.1 安装扩展 C 1.2 设置 1.3 使用 .clang-fornat 放置在项目(代码)文件夹下使用 .clang-fornat 为文件名 --- # https://clang.llvm.org/docs/ClangFormatStyle…

document360的替代品:原来它也这么好用

在当今信息爆炸的时代,企业和组织需要一个高效的知识管理系统来整理、存储和共享知识。document360是一款备受欢迎的知识库管理系统,但是它并非唯一的选择。本文将介绍document360的替代品,感兴趣就往下看吧。 首先,让我们来了解…

Python分析了京东7万+条评论,仅用3分钟,结果发现……

之前学习Python爬虫采集,为了练手用Scrapy写了一个爬虫,整整采集了京东平台vivo旗舰店7万多条评论。一直也没觉得这些评论数据有啥用,就留在MongoDB中吃灰。最近学了jieba和wordcloud之后,突发奇想着分析下这7万多条评论数据&…

【网络安全】上网行为代理服务器启用Alerts

文章目录 启用AlertsAlert Limits per 24 hoursEmail AlertsSystem Alerts Suspicious Activity AlertsPermitted Suspicious Activity AlertsBlocked Suspicious Activity Alerts Protocol&Category Usage Alerts告警邮件范例推荐阅读 这里的Web Proxy主要代指proxy serve…

HarmonyOS应用开发-搭建开发环境

本文介绍如何搭建 HarmonyOS 应用的开发环境,介绍下载安装 DevEco Studio 开发工具和 SDK 的详细流程。华为鸿蒙 DevEco Studio 是面向全场景的一站式集成开发环境,面向全场景多设备,提供一站式的分布式应用开发平台,支持分布式多…

声纹识别资源汇总(不断更新)

目录 一、任务说明二、指标三、声纹识别研究现状四、数据集开源(1)VoxCeleb:(2)WSJ and LibriSpeech Corpus(3)VOiCES Dataset(4)English Multi-speaker Corpus for Voic…

机器学习笔记(四)初识卷积神经网络

前言 第一次写卷积神经网络,也是照着paddlepaddle的官方文档抄,这里简单讲解一下心得。 首先我们要知道之前写的那些东西都是什么,之前写的我们称之为简单神经网络,也就是简单一层连接输出和输出,通过前向计算和逆向…

LM358 典型应用Multisim仿真设计

一、LM358简介: LM358 运算放大器属于一种低功率双运算放大器,由两个独立的高增益内部频率补偿运算放大器组成,专门设计用于在宽电压范围内由单电源供电。LM358 运算放大器具有低功耗、共模输入电压范围扩展到地/VEE以及单电源或双电源操作。…

代表团坐车 - 华为OD统一考试

OD统一考试(B卷) 分值: 100分 题解: Java / Python / C 题目描述 某组织举行会议,来了多个代表团同时到达,接待处只有一辆汽车可以同时接待多个代表团,为了提高车辆利用率,请帮接待…

Linux 系统拉取 Github项目

一、安装Git 在Linux上拉取GitHub项目可以使用Git命令。首先确保已经安装了Git。如果没有安装,可以通过包管理器(比如apt、yum)来进行安装。 sudo yum install git #查看安装版本 git -version二、关联GitHub 配置本地账户和邮箱 >>…

Redis缓存穿透,缓存击穿,缓存雪崩

文章目录 Redis缓存穿透,缓存击穿,缓存雪崩1. 缓存穿透1.1 解决方案1:缓存空数据1.2 解决方案2:使用布隆过滤器1.2.1 布隆过滤器介绍 2. 缓存击穿2.1 解决方案1:互斥锁2.2 解决方案2:逻辑过期 3. 缓存雪崩3…

抖店和商品橱窗有什么区别?新手应该选哪个?

我是电商珠珠 临近年底了,有的人已经开始为下一年筹谋,有的去抖音做账号做直播带货,不会直播带货的就想尝试做下抖店,来为以后的经济打基础。 刚想要接触却对这类有些迷糊,发现商品橱窗和抖店都可以卖货,…

k8s基础架构

k8s基础架构 创建pod流程 (1)用户通过kubectl向api-server发起创建pod请求; (2)apiserver通过对应的kubeconfig进行认证,认证通过后将yaml中的po信息存到etcd; (3)Contr…

Oracle笔记-查看表已使用空间最大空间

目前以Oracle18c为例,主要是查这个表USER_SEGMENTS。 在 Oracle 18c 数据库中,USER_SEGMENTS 是一个系统表,用于存储当前用户(当前会话)拥有的所有段的信息。段是 Oracle 中分配存储空间的逻辑单位,用于存…

Java智慧校园源码,SaaS云平台,私有云部署,移动端小程序使用小程序原生语言开发

系统概述: 电子班牌系统又称之为智慧班牌,是当前校园数字化信息化建设、文化建设的主流,是校园日常工作安排、校园信息发布、班级文化风采展示、课堂交流的重要应用载体。智慧班牌系统在传统信息发布和校园文化展示功能基础上,融…

Polygon zkEVM ROM Spearbit审计报告解读(2023年6月Dragon Fruit升级版本)

1. 引言 前序博客有: Polygon zkEVM Hexens审计报告解读Polygon zkEVM Spearbit审计报告解读(2022年12月版本)Polygon zkEVM Spearbit审计报告解读(2023年1月版本)Polygon zkEVM Spearbit审计报告解读(20…

计网自顶向下(多线程Web代理服务器)

目录 🌼前言 🌼多线程Web代理服务器 🎒过程 🏀解释 🌳代码 🌼前言 前置知识 (1)进程 与 线程 进程与线程的一个简单解释 - 阮一峰的网络日志 (ruanyifeng.com) (…

计算机组成原理 数据的表示与运算

文章目录 数据的表示与运算数据表示定点数的表示与运算定点数的表示无符号数有符号数定点整数定点小数四码反码补码移码 总结 定点数的运算算术移位原码反码补码总结 逻辑位移循环位移总结 加减运算原码加减法补码加减法 溢出判断采用一位符号位 浮点数的表示与运算表示IEEE 75…

【排序算法】【二叉树】【滑动窗口】LeetCode220: 存在重复元素 III

作者推荐 【二叉树】【单调双向队列】LeetCode239:滑动窗口最大值 本文涉及的基础知识点 C算法&#xff1a;滑动窗口总结 题目 给你一个整数数组 nums 和两个整数 indexDiff 和 valueDiff 。 找出满足下述条件的下标对 (i, j)&#xff1a; i ! j, abs(i - j) < indexDi…