【知识】缓存类型和策略
转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn]
如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~
目录
缓存读取策略
缓存写入策略
直写缓存写入策略
回写高速缓存写入策略
回写缓存写入策略
缓存替换策略
先进先出 (FIFO)
后进先出 (LIFO)
最近最少使用(LRU 缓存)
最不常用 (LFU 缓存)
最近使用(MRU 缓存)
总结
Types of caches and policies
缓存系统需要为应用程序保持微妙的平衡,因为它们有许多优点和缺点。如果操作得当,缓存可以提高性能,提高应用程序速度并降低成本。但是,缓存系统的集成会带来应用程序可靠性降级的风险。
缓存通常位于应用程序和数据库之间。它的唯一目的是以闪电般的速度提供应用程序请求的响应。为了使缓存正确地完成其工作,它需要明确定义的规则集,以确定它将如何获取保持相关性所需的数据。话虽如此,有各种类型的缓存系统由精心挑选的缓存策略管理,这些策略与数据读取和写入有关。
缓存读取和写入策略定义何时应更新缓存和主内存,以便在应用程序时保持数据的相关性和可靠性。系统或应用程序请求从缓存中检索数据,但该特定数据当前不在缓存内存中的事件称为缓存未命中。
缓存命中是指系统或应用程序发出请求以从缓存中检索数据,并且数据实际上存在并提供给应用程序。
cache 努力追求的是更多的 cache hits,其中包含主内存中数据的准确表示。这就是读写策略主要发挥作用的地方。缓存系统遵循的读写策略在很大程度上与缓存未命中和缓存命中的频率有关。
缓存读取策略
缓存读取策略描述了缓存在尝试从应用程序检索数据时的行为方式。如果引用了缓存但数据不存在,则主内存将负责提供所需的信息。这是我们希望尽量减少的情况,尤其是在我们的应用程序读取量很大的情况下。
缓存写入策略
当缓存写入策略管理数据更改时,缓存的更新方式。有三个主要的缓存写入策略。
- write-through 直写
- write-back 回写
- write-around 绕写
直写缓存写入策略
直写是一种高速缓存写入策略,其中数据同时写入高速缓存和相应的主内存位置。
直写的优势
- 简单
- 可靠
- 帮助数据恢复
- 解决不一致问题
直写策略简单可靠,因为我们的数据与主内存位置保持同步。对数据的任何写入都将导致对缓存进行调整,从而消除缓存过时的风险。在停电或系统故障的情况下,我们也有缓存来帮助恢复我们的数据。缓存可以用作备份。
直写的缺点
- 高写入流量 = 性能变差
- 延迟增加
直写策略质疑了为写入操作提供缓存的优势。为什么?缓存的重点是避免进入主内存,当涉及写入时,此策略会一对一地进入主内存。在高流量的情况下,写入两个源的性能不佳,并且容易受到延迟的影响。因此,直写缓存策略适用于写入量不高的应用程序。
回写高速缓存写入策略
回写是一种缓存写入策略,其中数据仅写入缓存。数据在后台以指定的时间间隔或特定条件写入主存储器中的相应位置。当写入 backing store 或 main memory 时,写入操作的完成确认保持未阻塞状态,因为此过程在后台进行。
回写的优点
- 低延迟
- 适用于写入密集型应用程序的高吞吐量
写入缓存比延迟写入内存要快得多。因此,回写解决方案可以管理更多的写入请求,并以低延迟完成请求。
回写的缺点
- 数据可用性/数据丢失风险
- 复杂
如果缓存失败,如果数据尚未在后台写入后备存储,我们将面临数据丢失的风险。与使用直写策略的缓存相比,回写式缓存的实现更复杂,因为缓存需要跟踪哪些数据仅存在于缓存中,但尚未存在于主内存中。任何尚未反映在缓存中的更新数据通常都会被标记为 dirty,以指示需要写入后备存储。当这些位置中的数据从缓存中逐出时,它们将被写回后备存储。删除规则的主要内存更新是一种称为延迟写入的效果。由于这个定义的规则,回写式缓存中的读取未命中通常会导致两次内存访问:一次用于将替换的数据从高速缓存写回存储,另一次用于检索所需的数据。当涉及到具有高写入量的应用程序时,回写缓存非常有用。
回写缓存写入策略
回写策略首先将写入直接发送到数据库。在完成对主内存的写入后,缓存会更新,或者缓存中的相应键被删除,以便在下次尝试从缓存中检索数据时触发更新。
回写的优势
- 最新的数据
- 容错
- 避免缓存泛洪
回写的缺点
- 读取延迟可能更高
- 可能更高的漏失率
绕写策略适用于那些写入相当频繁且不倾向于重新读取最近写入的数据的应用程序。使用此策略时的结果会导致缓存中的值往往被频繁读取。到目前为止提到但尚未明确讨论的一个细节是,在缓存空间有限的情况下,我们如何确定缓存中的字段何时需要替换。
缓存替换策略
缓存替换策略或缓存逐出算法控制数据被覆盖的情况。缓存逐出策略是必需的,因为缓存往往比主内存小得多,以保持成本效益和效率。
有几种常用的方法可用于确定何时替换存储在缓存系统中的数据。
- First in first out 先进先出 (FIFO)
- Last in first out 后进先出 (LIFO)
- Least recently used 最近最少使用(LRU 缓存)
- Least frequently used 最不常用 (LFU 缓存)
- Most recently used 最近使用(MRU 缓存)
先进先出 (FIFO)
如果熟悉 Queues,则 FIFO 缓存策略将包含相同的行为。
在 First in First Out 或FIFO 替换策略中,当没有足够的剩余空间时,首先添加到缓存中的任何项目也是第一个被驱逐的项目。缓存根据块的添加顺序驱逐块,而不考虑之前访问块的频率或次数。
后进先出 (LIFO)
如果熟悉 Stack 作为一种数据结构,那么 LIFO 或后进先出缓存同样遵循 Stack 的行为。
在 Last in First Out 或 LIFO 替换策略中,当剩余空间不足时,最后添加到缓存中的任何项目也是第一个被逐出的项目。
最近最少使用(LRU 缓存)
现在,这种缓存样式在实际环境中更加有趣和常见。LRU 缓存是常见的面试问题,具有高度适用性。Least Recently Used 或 (LRU Cache) 跟踪添加到缓存中的项目以及它们的使用时间。这意味着最后检索的项是第一个在新条目时从缓存中逐出的项。
检索到或添加到缓存中的任何项目都会显示在最前面,以指示使用它的新近度。如果添加了一个项目,我们可以根据添加/检索规则集的自然顺序来假设缓存中的最后一项是最近使用最少的项目。因此,在插入到没有空间的缓存时,可以从缓存中逐出最后一项。
最不常用 (LFU 缓存)
虽然这听起来与最近最少使用的缓存相似,但频率更多地关注从缓存中引用某个项目的次数!我们不是密切关注区块的最近访问时间,而是存储一个值来描述它被访问的次数。Least Frequently Used 或 (LFU Cache) 计算缓存中某个项目需要的频率。缓存中最常使用的那些项目将首先被丢弃。
最近使用(MRU 缓存)
对于 Most Recently Used 缓存或 MRU 缓存,您猜对了,最近使用的项目是缓存中第一个被替换的项目!您可能想知道为什么我们要从缓存中逐出最近使用的项目。
最近使用的缓存或 MRU 缓存适用于项目越旧,访问可能性越大的情况。偶尔,如果您刚刚看到了一些东西,那么您不太可能想再看到它!有关这种缓存样式的好处的更实际示例。想象一下,一个人正在评估最近交易的设备的质量。您刚刚检查了一部电话并确定它的质量更高。您想很快再次检查手机吗?可能不是!
最近使用的缓存或 MRU 缓存方法的工作方式是保留项目列表,如果插入新项目,则最近查看的项目将成为第一个被逐出的项目。
总结
缓存系统需要遵循规则集,这些规则集将确定缓存在执行其工作时的有效性。缓存命中率是衡量缓存能够成功完成的请求数与收到的请求数的指标。因此,缓存需要寻求提高其缓存命中率。缓存未命中率是衡量缓存无法成功完成的请求数与它收到的请求数的指标。缓存应寻求最小化缓存未命中率,同时确保数据保持相关性。那么,我们如何做到这一点呢?
缓存遵循读写策略,其中写入策略的几个示例包括:
- write-through 直写
- write-back 回写
- write-around 绕写
每种类型的保单都有需要考虑的权衡。应考虑应用程序需求,这些需求是通过评估应用程序的行为来确定的。
提出如下问题:应用程序是经常读取数据还是经常写入?应用程序写入的数据是立即读取,还是在一段时间后读取?最近读取的应用程序数据是否经常被重新读取?
每个应用程序都有适用的读写策略。每个策略都满足不同的需求。每种方法的缺点都需要仔细评估和监控。下一个要考虑的细节是,与主内存的大小相比,缓存只是一个很小的子集。由于缓存的大小有限,缓存还需要遵循一个策略,该策略控制何时将存储的数据替换为传入的新数据。这种类型的策略更广为人知的名称是缓存替换策略。
一些缓存替换策略:
- First in first out 先进先出 (FIFO)
- Last in first out 后进先出 (LIFO)
- Least recently used 最近最少使用(LRU 缓存)
- Least frequently used 最不常用 (LFU 缓存)
- Most recently used 最近使用(MRU 缓存)