10 分钟搞懂缓存设计策略

简介: 10 分钟搞懂缓存设计策略

在设计缓存系统时需要考虑不同缓存策略的优缺点和适用场景,通过了解和应用这些策略,可以优化缓存系统的性能和效率。原文: 6-Caching Strategies to Remember while designing Cache System

前言

缓存的目标是减少从原始数据源获取数据的次数,从而加快处理速度并减少延迟。


缓存可以在不同体系架构级别上实现,包括内存缓存、磁盘缓存、数据库缓存和 CDN 缓存。


可以用不同的技术缓存数据,每种技术都有其优缺点。比如内存缓存将数据存储在计算机主内存中,与磁盘缓存相比,可以实现更快的访问速度。


另一方面,磁盘缓存将数据存储在硬盘上,速度比内存慢,但相对访问远程数据源的速度还是要快得多。


使用数据库缓存,将频繁访问的数据存储在数据库中,从而减少从外部存储检索数据的需要。


最后,CDN 缓存将数据存储在分布式服务网络中,从而减少访问远程数据的时延。



目录

  1. 缓存系统关键性能指标
  2. 读密集型应用缓存
  3. 写密集型应用缓存
  4. 缓存失效方法
  5. 结论



缓存系统关键性能指标

为了提高缓存系统的效率和性能,非常重要的一点是需要监控各种指标,从而根据指标做出有关缓存系统的重要业务决策。


需要考虑的参数有:


  1. 缓存命中率: 该指标衡量请求项在缓存中被找到次数的百分比。较高的缓存命中率意味着缓存可以提供更多数据,从而减少访问外部存储并提高性能。
  2. 时延: 时延是指访问数据所需时间。在缓存系统中,较低的时延意味着数据服务速度更快,从而提高整体性能。
  3. 吞吐量: 吞吐量度量在给定时间范围内可以处理的数据量。高吞吐量的缓存系统可以处理更多请求,提供更多数据,从而提高整体性能。
  4. 缓存大小: 缓存大小是为缓存分配的内存或存储的容量。缓存大小会影响缓存命中率,较大的缓存可以提高命中率,但也会增加缓存解决方案的成本和复杂性。
  5. 缓存未命中率: 此指标度量请求项在缓存中找不到并且需要从外部存储中获取的次数百分比。高缓存未命中率意味着需要从外部存储获取更多数据,从而对性能造成影响。


如果一直监控这些性能指标,就可以据此优化缓存系统,以获得更高的吞吐量和更低的时延。



读密集型应用缓存

读密集型应用(如 Wordpress/静态图像网站)需要设计缓存系统,以支持更多的读缓存。


下面是一些有用的方法:


  • Cache-aside
  • Cache-through
  • Refresh-ahead
1. Cache-Aside


Cache-aside 方法是最常用的缓存策略之一。


方法


  1. 每当应用发送请求,首先检查缓存中是否有请求的数据。
  2. 如果有,返回缓存的数据。
  3. 否则,应用程序从数据库查询数据,并在返回途中更新缓存,然后返回数据。


优缺点


  • 每次缓存未命中都会导致三次访问,可能会造成明显的时延。
  • 如果有人更新数据库而不写入缓存,可能会读到过期数据。(因此,Cache-aside 通常与其他策略一起使用)。
2. Read-through


在 read-through 方法中,缓存对数据库进行读取/查询操作,然后更新自己并将请求数据返回给最终用户。


方法


  1. 应用程序每次都从缓存中查询数据。
  2. 如果数据不在缓存中,则缓存查询数据库并更新自己。
  3. 缓存将数据返回给最终用户。


优缺点


  • 简化应用程序代码,read-through 策略确保将数据获取逻辑转移到缓存中,从而简化了应用程序代码。
  • 更好的读取可伸缩性。当某个 key 在 Cache-aside 中过期时,并发请求可能会触发多次数据库查询相同的数据。在 Read-through 中,缓存确保只向数据库发送一个查询。
3. Refresh-ahead


Refresh-ahead 策略是在过期之前刷新缓存数据,该方法适用于热数据,即预计在不久的将来会被请求的数据。


方法


  1. 假设缓存数据的过期时间为 60 秒,刷新提前系数为 0.5。
  2. 如果缓存数据在 60 秒后被访问,将从缓存存储执行同步读取以刷新其值。
  3. 如果缓存数据在 30 秒后被访问,比如第 35 秒,缓存将直接返回数据,并异步刷新数据。


优缺点


因此,refresh-ahead 缓存本质上是在下一次可能的缓存访问之前以配置的间隔刷新缓存。在这种读流量非常高的系统中,几毫秒内可能会发生几千个读操作。



写密集型应用缓存

任何写密集型应用程序都需要缓存策略,例如:

1. Write-Through


Write-Through 策略将缓存作为其主数据存储,即首先在缓存中更新数据,然后才在数据库中更新数据。


下面是应用想要写入数据或更新值时发生的情况:


  1. 应用程序将数据直接写入缓存。
  2. 缓存更新主数据库中的数据。当写操作完成时,缓存和数据库都具有相同的值,并且始终保持一致。


优缺点


当与 read-through 配合使用时,在网络调用中非常有效,数据首先被读/写到缓存中,使得几乎不会发生缓存无效的情况。由于所有数据都是新的和经常访问的数据,而且所有对数据库的写入都是通过缓存完成,使得数据库和缓存几乎始终保持一致。

2. Write-back


Write-back 方法与 write-through 非常相似,只是数据库写调用是异步的。


优缺点


  1. Write-back 缓存可以提高写性能,非常适合涉及大量写操作的工作负载。当与 read-through 结合使用时,也非常适合混合工作负载,可以确保最近更新访问的数据始终在缓存中可用。
  2. 降低网络成本: 如果使用批处理调用,还可以减少对数据库的总体写操作,从而减少负载并降低成本,特别是当数据库按请求数量收费时(例如 DynamoDB)。
  3. 缓存使用效率低下: 不经常被请求的数据也会被写入缓存。这点可以通过 TTL 进行优化。
3. Write-around


在 Write-around 方法中,首先将数据更新到数据库,然后数据库对缓存进行异步调用以更新 key。


方法


  1. 当收到写请求时,应用程序更新数据库中的记录。
  2. 数据库异步更新/删除缓存中的键。


优缺点


Write-around 可以与 read-through 结合使用,在数据只写入一次,读取频率较低或从不读取的情况下提供良好的性能(例如实时日志或聊天室)。同样,这种模式也可以与 cache-aside 结合使用。



缓存失效方法

缓存失效是从缓存中删除陈旧或过时数据的过程,以确保只保留最新的可用数据。缓存失效策略有:


  1. 基于时间失效(TTL): 在此策略中,缓存数据在经过一段时间后失效。这是一个简单而有效的策略,易于实施,但可能并不适用于所有用例,因为有些数据可能比其他数据更容易过时。
  2. 基于事件失效: 在此策略中,缓存数据将根据发生的特定事件(如底层数据源更改或其他相关事件)失效。这是一种更有针对性的失效方法,可确保数据仅在必要时失效,但需要与应用和底层数据源进行更层次的集成。
  3. 基于版本失效: 在此策略中,为缓存中的每个数据块分配一个版本号,该版本号在每次数据更改时递增。当数据失效时,将在缓存中更新版本号,以确保仅使用数据的最新版本。这种策略对于频繁更改的数据效果很好,但需要额外的开销来管理版本号。
  4. 最近最少使用(Least recently used, LRU)失效: 在此策略中,当缓存达到容量限制时,缓存中最近最少使用的数据将失效,从而确保在缓存中保留最常用的数据,降低存储陈旧数据的风险。然而,该机制可能并不适合所有用例,因为有些数据可能不被经常访问,但仍然需要缓存。
  5. 手动失效: 在此策略中,失效由应用程序或管理员手动触发。该机制提供了最大的灵活性和对缓存的控制,但需要更多开销来管理失效过程。


具体失效方法包括清除、禁止、刷新等。



结论

总之,上文提到的策略永远不会单独或孤立的起作用,而总是组合工作。例如,Write-around 策略可以与 Cache-aside 策略一起实现,以确保数据一致性。更重要的是,应该了解应用程序的读/写访问模式,因为选择错误的组合可能无法带来最好的结果。


例如,如果在实际应该使用 write-around/read-through(写入的数据访问频率较低)时选择了 write-through/read-through,那么缓存中就会有无用的垃圾。




你好,我是俞凡,在 Motorola 做过研发,现在在 Mavenir 做技术工作,对通信、网络、后端架构、云原生、DevOps、CICD、区块链、AI 等技术始终保持着浓厚的兴趣,平时喜欢阅读、思考,相信持续学习、终身成长,欢迎一起交流学习。为了方便大家以后能第一时间看到文章,请朋友们关注公众号"DeepNoMind",并设个星标吧,如果能一键三连(转发、点赞、在看),则能给我带来更多的支持和动力,激励我持续写下去,和大家共同成长进步!

目录
相关文章
|
2月前
|
存储 缓存 UED
讲解移动应用中的缓存策略。
移动应用的缓存策略包括数据缓存、有效期管理、缓存逐出(如LRU)、网络状态适应、异步更新、缓存合并及离线支持。这些策略加速应用、减少网络请求,提升用户体验,但也需平衡数据新鲜度和实时性。正确选择和优化缓存策略对于性能和流量效率至关重要。
19 2
|
2月前
|
缓存 数据库 索引
如何优化Python Web应用的性能,包括静态资源加载、缓存策略等?
```markdown 提升Python Web应用性能的关键点:压缩合并静态资源,使用CDN,设置缓存头;应用和HTTP缓存,ETag配合If-None-Match;优化数据库索引和查询,利用数据库缓存;性能分析优化代码,避免冗余计算,使用异步处理;选择合适Web服务器并调整参数;部署负载均衡器进行横向扩展。每一步都影响整体性能,需按需调整。 ```
21 4
|
2月前
|
存储 缓存 算法
缓存淘汰策略
缓存淘汰策略
31 0
|
2月前
|
存储 缓存 NoSQL
后端开发中的缓存策略:提升应用性能的关键
后端开发中的缓存策略:提升应用性能的关键
30 0
|
19天前
|
存储 缓存 安全
基于iOS平台的高效图片缓存策略实现
【4月更文挑战第22天】 在移动应用开发中,图片资源的加载与缓存是影响用户体验的重要因素之一。尤其对于iOS平台,由于设备存储空间的限制以及用户对流畅性的高要求,设计一种合理的图片缓存策略显得尤为关键。本文将探讨在iOS环境下,如何通过使用先进的图片缓存技术,包括内存缓存、磁盘缓存以及网络请求的优化,来提高应用的性能和响应速度。我们将重点分析多级缓存机制的设计与实现,并对可能出现的问题及其解决方案进行讨论。
|
18天前
|
存储 缓存 编解码
实现iOS平台的高效图片缓存策略
【4月更文挑战第23天】在移动应用开发领域,尤其是图像处理密集型的iOS应用中,高效的图片缓存策略对于提升用户体验和节省系统资源至关重要。本文将探讨一种针对iOS平台设计的图片缓存方案,该方案通过结合内存缓存与磁盘缓存的多层次结构,旨在优化图片加载性能并降低内存占用。我们将深入分析其设计理念、核心组件以及在实际场景中的应用效果,同时对比其他常见缓存技术的优势与局限。
|
19天前
|
存储 缓存 算法
实现iOS平台的高效图片缓存策略
【4月更文挑战第22天】在移动应用开发中,图片资源的处理是影响用户体验的重要因素之一。特别是对于图像资源密集型的iOS应用,如何有效地缓存图片以减少内存占用和提升加载速度,是开发者们面临的关键挑战。本文将探讨一种针对iOS平台的图片缓存策略,该策略通过结合内存缓存与磁盘缓存的机制,并采用先进的图片解码和异步加载技术,旨在实现快速加载的同时,保持应用的内存效率。
|
1月前
|
缓存 关系型数据库 MySQL
MySQL 查询优化:提速查询效率的13大秘籍(索引设计、查询优化、缓存策略、子查询优化以及定期表分析和优化)(中)
MySQL 查询优化:提速查询效率的13大秘籍(索引设计、查询优化、缓存策略、子查询优化以及定期表分析和优化)(中)
|
6天前
|
缓存 监控 NoSQL
Redis缓存雪崩及应对策略
缓存雪崩是分布式系统中一个常见但危险的问题,可以通过合理的缓存策略和系统设计来降低发生的概率。采用多层次的缓存架构、缓存预热、合理的缓存失效时间等措施,都可以有效应对缓存雪崩,提高系统的稳定性和性能。在实际应用中,及时发现并解决潜在的缓存雪崩问题,是保障系统可用性的关键一环。
36 14
|
17天前
|
缓存 监控 算法
软件体系结构 - 缓存技术(6)淘汰策略
【4月更文挑战第20天】软件体系结构 - 缓存技术(6)淘汰策略
87 12