理解缓存抽象

缓存与缓冲区的区别

术语“缓冲区”和“缓存”往往被互换使用。然而,请注意,它们代表不同的东西。传统上,缓冲区用作快速实体和慢实体之间数据的中间临时存储。由于一方必须等待另一方(这会影响性能),缓冲区通过允许整块数据一次性移动而不是小块来缓解这一问题。数据仅从缓冲区中写入和读取一次。此外,缓冲区对至少一个知道其存在的一方是可见的。

另一方面,缓存根据定义是隐藏的,没有一方知道缓存正在发生。它也提高性能,但是通过让相同的数据以快速方式多次读取来实现。

您可以在这里找到有关缓冲区和缓存之间区别的进一步解释。

在其核心,缓存抽象将缓存应用于Java方法,从而根据缓存中可用的信息减少执行次数。也就是说,每次调用目标方法时,抽象都会应用一种缓存行为,检查该方法是否已针对给定参数调用过。如果已调用,则返回缓存的结果,而无需调用实际方法。如果方法尚未调用,则调用该方法,并将结果缓存并返回给用户,以便下次调用该方法时返回缓存的结果。通过这种方式,昂贵的方法(无论是CPU绑定还是IO绑定)只能针对给定参数集调用一次,并且可以重复使用结果,而无需实际调用该方法。缓存逻辑透明应用,不会干扰调用者。

此方法仅适用于保证对于给定输入(或参数)无论调用多少次都会返回相同输出(结果)的方法。

缓存抽象提供其他与缓存相关的操作,例如更新缓存内容或删除一个或所有条目的能力。如果缓存处理可能在应用程序过程中发生变化的数据,则这些操作非常有用。

与Spring Framework中的其他服务一样,缓存服务是一个抽象(而不是缓存实现),需要使用实际存储来存储缓存数据,即,该抽象使您无需编写缓存逻辑,但不提供实际数据存储。这种抽象由org.springframework.cache.Cacheorg.springframework.cache.CacheManager接口实现。

Spring提供了几种实现该抽象的方式:基于JDK的java.util.concurrent.ConcurrentMap缓存,Gemfire缓存,Caffeine,以及符合JSR-107的缓存(如Ehcache 3.x)。有关插入其他缓存存储和提供程序的更多信息,请参阅插入不同的后端缓存

缓存抽象对多线程和多进程环境没有特殊处理,这些功能由缓存实现处理。

如果您有多进程环境(即在多个节点上部署的应用程序),则需要相应地配置缓存提供程序。根据您的用例,多个节点上的相同数据副本可能足够。但是,如果在应用程序过程中更改数据,则可能需要启用其他传播机制。

缓存特定项等同于典型的get-if-not-found-then-proceed-and-put-eventually代码块,这些代码块在程序化缓存交互中找到。不会应用锁,并且多个线程可能同时尝试加载相同的项。逐出也是如此。如果多个线程尝试同时更新或逐出数据,则可能使用过时数据。某些缓存提供程序在该领域提供高级功能。有关更多详细信息,请参阅您的缓存提供程序的文档。

  • 缓存声明:识别需要进行缓存的方法及其策略。

  • 缓存配置:存储数据并从中读取数据的后备缓存。