什么是缓存?
为什么需要缓存
现代软件系统已经变得越来越分布和复杂。这带来了许多挑战和问题,特别是与系统性能相关的问题。系统的缓慢可能导致公司丧失信誉和盈利能力。
下图显示了现代分布式体系结构的一个非常直观的视图。注意,实际的体系结构将更加复杂,许多微服务(包括内部和外部)将作为流的一部分执行。在系统的设计中,还会有其他组件,比如消息传递系统、 LDAP、规则引擎等等。
图1: 软件系统的层次
如上图所示,不同组件之间存在大量交互,完成单个请求需要使用跳数。由于组件的处理时间和等待下游组件响应的等待时间,这增加了每个接触点的延迟。
请注意,处理时间可能是由应用程序本身或下游系统花费的时间决定的,也可能是由 络(DNS 查找、建立连接、 络传输时间等)决定的。
这就是缓存通过将数据副本保存在应用程序的客户机/组件附近来帮助系统提高性能的地方。
缓存是如何工作的
如上面的图1所示,在软件系统中可以有不同的层和交互。缓存可以应用于任何层,但是缓存操作的基本原理保持不变。缓存的数据将用于避免昂贵的 络跳转、来自底层数据库的调用或缓慢的存储系统。
下图显示了缓存在特定场景中的工作方式。这可以通过以下步骤来解释。请注意,在不同的场景中,缓存的实现可能有所不同,但是在高层次上,这种方法仍然是相同的。
使用缓存的优点
- 更好的应用程序性能: 使用缓存的主要优点是它提高了应用程序的性能。由于所请求的数据通常在应用程序附近可用,因此在快速内存访问中,可以将其返回并重用以进行进一步处理。这有助于提高应用程序的性能
- 避免不必要的磁盘访问/ 络跃点: 由于所请求的数据通常在应用程序附近可用,在快速内存访问中,这可以帮助避免不必要的跳转到较慢的组件,如 DB、磁盘,或通过 络对其他组件/系统进行调用。这再次有助于提高应用程序的性能
- 数据库更好的可伸缩性: 由于现在对数据库的查询较少,因此可以释放其容量来处理其他请求。这可以减少数据库负载/成本并提高可伸缩性。其他后端系统/组件也是如此
使用缓存时的重要注意事项
在为给定场景设计缓存框架时,必须做出一些重要的决定。以下是缓存设计的一些关键方面的摘要:
- 您应该缓存多少数据?
- 在缓存中插入新数据时,必须删除或保留哪些数据?
- 缓存中的数据是否仍然相关,还是已经过时或过时?
- 如何保持缓存中的数据是最新的?
- 你怎样才能保持缓存-错过低?
缓存的类型/风格以及各种缓存策略方法将在以下部分中讨论。我们将研究它们如何影响缓存行为,并解决上面提到的一些问题。
Cache 的多种口味
在本节中,我们将讨论各种策略,这些策略通常用于管理更新底层数据存储的场景。正如前一节所提到的,缓存错过率应该保持在低水平。
缓存未命中是在缓存中找不到请求的数据的场景,而缓存命中是在缓存中找到请求的数据并且不需要从源中检索的场景。
为了保持缓存丢失率较低,缓存数据应该是最新的。根据应用程序模式的不同,可以使用下列技术之一来确保缓存中的数据尽可能最新。
- 通过缓存写入: 在这种技术中,首先在缓存中更新数据,然后是源系统。这将确保缓存始终拥有最新更新的数据。但是,这会引入源系统上发生的写操作的延迟。如果应用程序是写密集型的,则不推荐使用此方法
- 写回缓存: 为了克服通过缓存写入的问题,使用了这种技术。类似地,在这种情况下也首先更新缓存。但是,缓存中更新的数据将异步同步回源系统。如果应用程序需要更高级别的源系统一致性,则不推荐使用这种技术
- 写缓存周围: 在这种技术中,数据直接在源中更新。缓存将定期刷新,以更新数据存储中的数据。这有可能获得过时的数据或增加缓存丢失
缓存刷新策略示例
本节总结了用于刷新缓存内容的一些最流行的技术。可能需要刷新缓存的原因有多种。由于缓存大小通常比源小得多,因此不能缓存所有数据。随着缓存大小随着时间的推移而增长,它可能会变得满。用更需要或更常用的数据替换缓存中的旧数据将导致更低的缓存丢失。下面是刷新缓存常用技术的列表。
- 最近使用(MRU): * 在这种方法中,首先丢弃最近使用的物品,然后用新物品取而代之
- Least recently used (LRU) : 在这种方法中,最近使用次数最少的项目首先被丢弃,然后被一个新项目取代
- First in, first out (FIFO) 先进先出(FIFO): 在这种技术中,首先丢弃要插入到缓存中的第一个项,然后用一个新项替换
- Last in, first out (LIFO) 后进先出(LIFO): : 在这种技术中,首先丢弃要插入到缓存中的最后一个项,并由新项替换
- Least frequently used (LFU) 最少使用(LFU): : 在这种技术中,在缓存中使用最少的项首先被丢弃,并由一个新项替换
- 大部分requently used (MFU) 经常使用(MFU): 在这种技术中,首先丢弃缓存中最常用的项,然后用新项替换
跨层缓存
下表总结了如何在软件系统中跨层使用缓存。还突出显示了一些工具/框架,它们可用于在给定场景中实现缓存。
注意,在软件应用程序中,缓存可以应用于一个或多个层。
图层/组件 |
缓存在哪里 |
缓存什么 |
工具/框架 |
络客户端 |
Web/Mobile 浏览器 |
图像/字体和媒体文件 |
|
络服务器 |
络服务器 |
动态内容,避免应用服务器过载 |
使用反向代理 |
CDN |
内容传递 路 |
静态响应和 API 响应 |
像 AWS CloudFront、 Akamai 等 CDN。 |
应用/服务层(L1) |
在应用服务器上 |
动态服务器响应 |
自定义逻辑或者可以使用由各种框架(如 Hibernate)提供的内存特性 |
分布式/内存缓存(L2) |
在内存中运行的单独群集上。可供多个应用程序使用。 |
通常数据存储在键值对中。也可用于无状态应用程序的会话管理。 |
Redis, MemCached, AWS ElasticCache, HazelCast Redis,MemCached,AWS ElasticCache,HazelCast |
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!