缓存、分布式缓存、缓存的风险

news/2025/2/22 3:05:16/

为系统引入缓存的理由

在软件的开发中,引入缓存的负面作用明显大于硬件的缓存。主要由以下几个方面
从开发者角度来说引入缓存会提高系统的复杂度,因为你需要考虑缓存的失效、更新、一致性等问题(硬件缓存也存在这些问题,只是不需要你考虑了)
从运维角度来说 缓存会掩盖掉一些缺陷,让问题在更久的时间以后,出现在距离发生现场更远的位置上;缓存还可能存在泄漏某些保密数据,这也是容易攻击的薄弱点
存在这么多问题,为什么系统还会引入缓存呢
第一种为了缓解CPU压力而做的缓存
比如说,把方法运行的结果存储起来、把原本要实时计算的内容提前算好、把一些公用的数据进行复用等等,这些引入缓存的做法,都可以节省CPU算力,顺带提升响应性能
第二种,为了缓解I/O压力而做缓存
比如说,通过引入缓存,把原本对网络、磁盘等较慢介质的访问;把原本对单点部件(如数据库)的读写访问,变为可扩缩部件(如缓存中间件)的访问,等等,也顺带提升了响应性能
最后能通过花钱,(比如扩服务器的数量)来满足需要的话,那升级硬件往往是更好的解决方案

缓存属性

通常我们在设计或选择缓存时,至少需要考虑以下四个维度的属性
吞吐量:缓存的吞吐量使用QPS来衡量,它反映了对缓存进行并发读、写操作的效率,即缓存本身工作效率的高低
命中率 缓存的命中率即成功从缓存中返回结果次数与总请求次数的比值,它反映了引入缓存的价值高低、命中率越低,引入缓存的收益越小,价值越低
**扩展功能:**缓存处理基本读写功能外,还提供了一些额外的管理功能,比如最大容量,失效时间、失效事件、命中率统计等
分布式支持缓存可以分为进程内缓存和分布式缓存两大类,前者只为节点本身提供服务,无网络访问操作,速度快,但缓存的数据不能在各个服务节点中共享。后者则相反

缓存最主要的数据竞争来源于读取数据的同时,也会伴随着对数据状态的写入操作,而写入数据的同时,也会伴随着数据状态的读取操作。
一种是以Guava Cache 为代表的同步处理机制,即在访问数据时一并完成缓存、淘汰、失效等状态变更操作,通过分段加锁等手段来尽量减少数据竞争。
另外一种是以Caffeine为代表的异步日志提交机制。这种机制参考了经典的数据库设计理论,它把对数据的读、写过程看作是日志(即对数据的操作指令)的提交过程

命中率与淘汰策略

第一种:FIFO(First In First Out)
即优先淘汰最早进入被缓存的数据。这个淘汰策略并不优秀,因为越是访问频繁的数据,往往越会早早地被存入缓存中。所以这种淘汰策略,很可能会大幅度降低缓存的命中率
第二种:LRF(Least Recent Used)
即优先淘汰最久未被使用访问过的数据。LRU通常会采用HashMap加LinkedList的双重结构(如LinkedHashMap)来实现。也就是,它以HashMap来提供访问接口,保证常量时间的读取性能,以LinkedList的链表元素顺序来表示数据的时间顺序,在每次命中缓存时,把返回对象调整到LinkedList开头,每次缓存淘汰时从链表末端开始清理

第三种 :LFU (Least Frequently Used)
即优先淘汰掉最不经常使用的数据。LFU会给每个数据添加一个访问计数器,每访问一次就加1,当要淘汰数据的时候,就清理计数器数值最小的那批数据**。第一个问题**这个的缺点就是需要针对每个缓存数据都专门去维护一个计数器,每次访问都要更新,吞吐量会降低。第二个问题不便于处理随时间变化的热度变化,比如某个曾经频繁访问的数据现在不需要了,它也很难被自动清理出缓存。
TinyLFU
TinyLFU时LFU的改进版。为了缓解LFU每次访问都需要修改计数器所带来的性能负担。TinyLFU 首先采用Sketch结构来分析访问数据,所谓的Sketch,它实际上是统计学中的概念。即采用少量样本数据来估计全部样本数据的特征。
借助Count-Min-Sketch 算法(类似布隆过滤器的一种等价变种结构)可以用相对小得多的记录频率和空间,来近似地找出缓存中的低价值数据
另外为了解决LFU不便于处理时间变化的热度变化问题,TinyLFU采用基于“滑动时间窗口“的热度衰减算法。简单理解就是每隔一段时间,会把计数器的数值减半,以此解决”旧热点“数据难以清除的问题

分布式缓存如何与本地缓存配合,提高系统性能

复制式缓存与集中式缓存
复制式缓存,你可以看作是能够支持分布式的进程内缓存。它的工作原理与Session复制类似,缓存中的所有数据,在分布式集群的每个节点里面都存一份副本,当读取数据时,无需网络访问,直接从当前节点的进程内存中返回。读取效率很高,但是当数据变更时,就必须遵从复制协议,将变更的数据同步到集群的每一个节点,代价很高,在小规模集群中还算可以,但是在大规模集群下,网络同步速度跟不上写的速度,进而导致内存中有大量的待重发对象,最终导致OOM
集中式缓存,集中式缓存是目前分布式缓存中的主流形式。集中式缓存的读写都需要网络访问,它的好处就是不会随着集群的节点数量增加而增加额外的负担
透明多级缓存 分布式缓存和进程内缓存,各有所长,也各有局限,它们是互补的,而不是竞争关系,而多级缓存就是,使用进程内缓存做一级缓存,分布式做二级缓存,如果能在一级缓存中查询到结果接直接返回,否则就到二级缓存中去查询,再将二级缓存的结果回填到一级缓存,以后的访问就没有网络请求了。但是我们需要透明的解决这些问题,多级缓存才有意义。一种常见的设计原则,就是变更以分布式缓存中的数据为准,访问以进程内缓存的数据优先
大致做法就是当数据发生变动时,在集群内发送推送通知(简单点可以使用Redis的发布订阅模式,求严谨也可以引入Zookeeper或Etcd来处理),让各个节点的一级缓存自动失效掉响应的数据。
然后,当访问缓存时,缓存框架封装好一二级缓存联合查询接口,接口外部只查询一次,接口内部实现优先查询一级缓存。如果没获取到数据,就再自动查询二级缓存

缓存的风险

缓存穿透
如果查询的数据数据库中根本就不存在的话,缓存里面自然也不会有。这样请求的流量每次都不会命中,每次都会打到末端数据库,缓存自然就起不到缓存压力的作用了。这种现象就是缓存穿透
对于业务逻辑本身就不能避免的缓存穿透
我们可以约定在一定时间内,对返回为空的Key值依然进行缓存(注意正常返回,但是结果为空,不要把抛异常的当作空值缓存了)这样在一段时间内只会被穿透一次。如果后续业务在数据库中对该Key值插入新的记录,那我们就应当在插入之后主动清理掉缓存的Key值,如果业务实效性允许的话,也可以设置一个较短的超时时间来自动处理缓存
对于恶意攻击导致的缓存穿透
针对这种原因,我们通常会在缓存之前设置一个布隆过滤器来解决。所谓的恶意攻击是指,请求者刻意构造数据库中肯定不存在的Key值,然后发送大量请求进行查询,而布隆过滤器是最小的代价,来判断某个元素是否存在某个集合的办法。
如果布隆过滤器给出的判断结果是请求数据不存在,那直接返回即可,连缓存都不必去查。虽然维护布隆过滤器需要一定的成本,但是比起攻击造成的损失损耗,还是比较值得

缓存击穿
缓存中的某些热点数据忽然因为某种原因失效了,比如典型的超期而失效,而此时又有了多个针对该数据的请求同时发送过来,那么这些请求就会全部未能命中缓存,都打到真实的数据库了,导致压力剧增,甚至宕机。这种现象,就被称为缓存击穿。
如果要避免我们通常可以采用这样两种方法
1、加锁同步。以请求该数据Key值为锁,这样只有第一个请求可以流入真实的数据源中,其他线程采用阻塞或者重试策略。如果是进程内缓存出现了问题,施加普通互斥锁就可以了,如果是分布式缓存问题,就实施分布式锁
2、热点数据由代码来手动管理。缓存击穿是指针对热点数据被自动失效才引发的问题,所以针对这类数据,我们可以通过代码来有计划的实现更新、失效、避免缓存的策略自动管理

缓存雪崩
大量的数据同时失效,那么之所以会出现这样的情况,往往是因为系统有专门的缓存预热功能,也可能是因为,大量的公共数据都是由某一次冷操作加载的,这样可能会出现又一次载入的缓存的大批数据具有相同的过期时间,在同一时刻一起失效。
还有一种情况就是因为缓存服务因为某些原因崩溃重启后,此时会造成大量数据同时失效。
而避免缓存雪崩问题,我们通常可以采取这三种方法
1、提升系统的可用性,建设分布式缓存的集群
2、启用透明多级缓存,各个服务器节点的一级缓存中的数据,通常会具有不一样的加载时间,这样做也就分散了它们的过期时间
3、将缓存的生存期从固定时间改为一个时间段内的随机时间

缓存污染
所谓的缓存污染,就是指,缓存中的数据与真实数据源中的数据不一致的现。
为了提高使用缓存时的一致性,人们总结了不少遵循的设计模式,介绍一种Cache Aside模式,因为这种设计模式最简单,成本也最低。它的主要内容就两条
读数据时,先读缓存,缓存没有的话,再读数据源,然后将数据放入缓存,再响应请求
写数据时,先写数据库,然后失效(而不是更新)掉缓存
一个是先数据源后缓存
二个是应当先失效缓存,而不是尝试更新缓存


http://www.ppmy.cn/news/1414066.html

相关文章

多轴机械臂/正逆解/轨迹规划/机器人运动学/Matlab/DH法 学习记录01——数学基础

系列文章目录 本科毕设正在做多轴机械臂相关的内容,这里是一个学习机械臂运动学课程的相关记录。 如有任何问题,可发邮件至layraliufoxmail.com问询。 1. 数学基础 文章目录 系列文章目录一、空间位置、姿态描述二、旋转矩阵(Rotation matri…

网络安全加密算法---对称加密

三位同学一组完成数据的对称加密传输。 三位同学分别扮演图中 A、B 和 KDC 三个角色,说明 KA、KB,KAB 和发送的数据Data 的内容。 给出图中 2 和 3 中的数据,以及 Data 加密后的密文。可以完成多轮角色互换的通信 过程。其中一轮过程要求 K…

信息系统项目管理师0044:IT治理方法与标准(3信息系统治理—3.1 IT治理—3.1.4 IT治理方法与标准)

点击查看专栏目录 文章目录 3.1.4 IT治理方法与标准1. ITSS中1T服务治理 3.1.4 IT治理方法与标准 考虑到IT治理对组织战略目标达成的重要性,国内外各类机构持续研究并沉淀IT治理相关的最佳实践方法、定义相关标准,这里面比较典型的是我国信息技术服务标准…

Linux进阶篇:centos7扩展root分区:LVM应用案例

centos7扩展root分区:LVM应用案例 当服务器根分区或者是root分区存储空间快用完的时候,并且重要的数据都在root分区下,当如何应对,没关系坐好,分分钟解决它,我们可以进行分区扩容。 一 添加一块新的硬盘 …

动手学习深度学习(李沐)

文章目录 04.数据操作 04.数据操作 创建数组 形状 每个元素的数据类型 每个元素的值 数据操作

React中的ref有什么用?

React中的ref有什么用? 1. 为什么使用refs?1.1 Refs在以下场景中非常有用:1.2 如何创建和使用refs?1.2.1 使用createRef方法1.2.2 使用useRef钩子 2. 使用场景2.1使用ref进行DOM测量2.2 集成第三方库 3. Refs与函数组件3.1 使用us…

极狐GitLab 如何在 helm 中恢复数据

本文作者:徐晓伟 GitLab 是一个全球知名的一体化 DevOps 平台,很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版,专门为中国程序员服务。可以一键式部署极狐GitLab。 本文主要讲述了如何在极狐GitLab …

2024中国航空航天暨无人机展览会8月在重庆举办

2024中国航空航天暨无人机展览会8月在重庆举办 邀请函 主办单位: 中国航空学会 重庆市南岸区人民政府 招商执行单位: 重庆港华展览有限公司 展会背景: 为更好的培养航空航天产业人才,汇聚航空教育产业创新科技,…