译者 | 李睿
审校 | 孙淑娟
本文面向软件开发人员、技术经理、软件架构师、测试工程师以及其他有兴趣了解如何在软件系统中使用缓存的人员。
1.缓存是什么?
(1)为什么需要缓存
如今,现代软件系统变得越来越分散和复杂,带来了许多挑战和问题,尤其是与系统性能相关的问题。系统运行缓慢可能会导致企业失去信誉和盈利能力。
下图显示了现代分布式架构的一个非常简单的视图。需要注意的是,实际架构会更加复杂,因为许多微服务(内部和外部)作为流程的一部分执行。在系统设计中还会有其他组件,例如消息传递系统、LDAP、规则引擎等。
软件系统的层级如上图所示,不同组件之间存在大量的交互,需要跳转来完成单个请求。由于组件的处理时间和等待下游组件响应的等待时间的累积,将会增加每个接触点的延迟。
需要注意的是,处理时间可能是由于应用程序本身或下游系统所花费的时间,也可能是由于网络(例如DNS查找、建立连接、网络传输时间等)的延迟。
缓存通过将数据副本保存在应用程序的客户端/组件附近来帮助提高系统性能来发挥重要作用。
(2)缓存的工作原理
如上图所示,软件系统中可以有不同的层和交互。缓存可以应用于任何一层,但缓存操作的基本原理保持不变。缓存数据将用于避免代昂贵的网络跳变、来自底层数据库的调用或存储速度较慢的存储系统。下图显示了缓存在特定场景中的工作方式。这可以通过以下步骤顺序来解释。需要注意,在各种场景中缓存的实现可能会有所不同,但在较高层次上,基本方法保持不变。
- 系统/组件接收发送回请求数据的请求。
- 它将检查请求的数据是否在缓存中。
- 如果数据在缓存中,将返回相同的缓存数据。
- 否则,系统将从源(例如数据库、外部系统或API调用)获取数据,并将使用这数据填充缓存。
- 最后,此数据将返回给调用者。
(3)使用缓存的优点
- 更好的应用程序性能:使用缓存的主要优点是它提高了应用程序的性能。由于所请求的数据通常在更靠近应用程序的地方可用,因此在快速内存访问中,它可以被返回并重新用于进一步处理。这有助于提高应用程序的性能。
- 避免不必要的磁盘访问/网络跳变:由于请求的数据通常在靠近应用程序的地方可用,在快速的内存访问中,这可以帮助避免不必要的跳变到较慢的组件,例如数据库、磁盘或调用其他组件/系统通过网络。这也有助于提高应用程序性能。
- 更好的数据库扩展性:由于现在对数据库的查询减少了,其容量被释放来处理其他请求。这可以减少数据库负载/成本,并提高可扩展性。其他后端系统/组件也是如此。
(4)使用缓存时的重要注意事项
在为给定场景设计缓存框架时,必须做出一些重要的决定。以下是缓存设计的一些关键方面的总结:
- 应该缓存多少数据?
- 在缓存中插入新数据时,哪些数据必须删除或保留?
- 缓存中的数据是否仍然相关,或者是否过时?
- 如何使缓存中的数据保持最新?
- 如何保持更低的缓存未命中率?
缓存的类型/风格和各种缓存策略方法将在以下部分中讨论。以下了解这些影响缓存的行为,并解决上面提出的一些问题。
(5)多种风格的缓存
本文将讨论通常用于管理底层数据存储更新场景的各种策略。如上所述,缓存未命中率应保持在较低水平。
缓存未命中是指在缓存中找不到请求的数据的情况,而缓存命中是指在缓存中找到请求的数据且无需从源中检索的情况。
为了保持更低的缓存未命中率,缓存数据应保持最新状态。根据应用程序模式的不同,可以使用以下技术之一来确保缓存中的数据尽可能是最新的。
- 直写缓存:在这种技术中,数据首先在缓存中更新,然后是源系统。这将确保缓存始终具有最近更新的数据。但是,这会导致源系统上发生的写入操作延迟。如果应用程序是写密集型的,则不建议使用这一方法。
- 回写缓存:为了克服直写缓存的问题,可以使用回写缓存技术。同样在这种情况下,缓存也是首先更新的。但是,缓存中的更新数据会异步同步回源系统。如果应用程序需要更高级别的源系统一致性,这并不是让人推荐的技术。
- 绕写缓存:在这种技术中,数据直接在源系统中更新。缓存将定期刷新,以更新数据存储中的数据。这有可能会获取过时数据或提高缓存未命中率。
2.缓存刷新策略示例
以下总结了一些用于刷新缓存内容的最流行的技术,可能有多种原因需要刷新缓存。由于缓存大小通常比源小得多,因此并非所有数据都可以缓存。随着缓存大小随时间增长,它可能会变满。采用更需要或更常用的数据替换缓存中的旧数据将降低缓存未命中率。以下是刷新缓存项目的常用技术列表。
(1)最近使用(MRU):在这种技术中,最近使用的缓存项目首先被丢弃,并被新项目替换。
(2)最近最少使用(LRU):在这种技术中,最近最少使用的项目首先被丢弃,并被新项目替换。
(3)先进先出(FIFO):在这种技术中,要插入缓存的第一个项目首先被丢弃,并被新项目替换。
(4)后进先出(LIFO):在这种技术中,要插入缓存中的最后一个项目首先被丢弃,并被新项目替换。
(5)最近最不常用(LFU):在这种技术中,缓存中使用最少的项目首先被丢弃,并被新项目替换。
(6)最常用(MFU):在这种技术中,缓存中最常用的项目首先被丢弃,并被新项目替换。
3. 跨层缓存
下表总结了如何在软件系统中跨层使用缓存,还重点介绍了一些工具/框架,它们可用于在给定场景中实现缓存。
需要注意的是,在软件应用程序中,缓存可以应用于一层或多层。
原文链接:https://dzone.com/articles/caching-across-layers-in-software-architecture