Spring缓存实现
Spring caching implementation
我正在探索 spring 缓存设施。我对此几乎没有疑问。
首先,它应该应用在服务方法级别还是DAO方法级别,服务方法正在调用DAO方法。
其次,如何避免缓存数据过时?
IMO,这两个问题的答案都是“视情况而定”。
从技术上讲,Spring明智的是,应用于 Service 和 DAO 的缓存注释都可以工作,我认为没有任何区别,所以归结为具体的用例。
例如,如果您“逻辑上”计划提供一个可缓存的抽象,作为在服务器上完成的某些计算过程的结果应该计算的内容,您最好在服务级别使用缓存。
另一方面,如果您在 dao 中有一个类似于 Something getSomethingById(id)
的 DAO 方法,并且您希望避免对底层数据库进行相对昂贵的调用,则可以在该级别提供缓存道的。话虽如此,如果您有 List<Something> fetchAll()
或 List<Something> fetchAllByFilter()
之类的方法,那么应用缓存可能不会有用。如果您正在使用 JPA(使用 Hibernate 实现),它们有自己的缓存抽象,但这超出了问题的范围,只是您应该注意的事情...
互联网上有很多教程,一些说明了基于服务的方法,一些用于 DAO 的方法注释,但同样,这些只是简单的示例,在现实世界中你必须做出决定。
现在关于第二个问题。一般来说,如果您的数据变化不大,缓存是有意义的,所以首先如果它经常变化,那么缓存可能不是 appropriate/relevant 对于用例。
除此之外还有很多技巧:
- 缓存数据逐出(通常基于时间)。参见 this tutorial
- 某种消息传递系统将发送有关缓存条目更改的消息。如果您有一个分布式应用程序并且仅保留缓存 in-memory,则此方法特别有用。收到消息时,您可能会选择“缓存复制”或完全清除缓存,以便最终“填充”新数据
- 使用分布式缓存技术,如 Hazelcast 或 Redis,而不是 in-memory 缓存。这样从技术上讲,缓存数据的一致性将由缓存提供程序来保证。
我还想向您推荐 This tutorial - 演讲者谈到了缓存实现的不同方面,我认为它与您的问题非常相关。
我正在探索 spring 缓存设施。我对此几乎没有疑问。
首先,它应该应用在服务方法级别还是DAO方法级别,服务方法正在调用DAO方法。
其次,如何避免缓存数据过时?
IMO,这两个问题的答案都是“视情况而定”。
从技术上讲,Spring明智的是,应用于 Service 和 DAO 的缓存注释都可以工作,我认为没有任何区别,所以归结为具体的用例。
例如,如果您“逻辑上”计划提供一个可缓存的抽象,作为在服务器上完成的某些计算过程的结果应该计算的内容,您最好在服务级别使用缓存。
另一方面,如果您在 dao 中有一个类似于 Something getSomethingById(id)
的 DAO 方法,并且您希望避免对底层数据库进行相对昂贵的调用,则可以在该级别提供缓存道的。话虽如此,如果您有 List<Something> fetchAll()
或 List<Something> fetchAllByFilter()
之类的方法,那么应用缓存可能不会有用。如果您正在使用 JPA(使用 Hibernate 实现),它们有自己的缓存抽象,但这超出了问题的范围,只是您应该注意的事情...
互联网上有很多教程,一些说明了基于服务的方法,一些用于 DAO 的方法注释,但同样,这些只是简单的示例,在现实世界中你必须做出决定。
现在关于第二个问题。一般来说,如果您的数据变化不大,缓存是有意义的,所以首先如果它经常变化,那么缓存可能不是 appropriate/relevant 对于用例。
除此之外还有很多技巧:
- 缓存数据逐出(通常基于时间)。参见 this tutorial
- 某种消息传递系统将发送有关缓存条目更改的消息。如果您有一个分布式应用程序并且仅保留缓存 in-memory,则此方法特别有用。收到消息时,您可能会选择“缓存复制”或完全清除缓存,以便最终“填充”新数据
- 使用分布式缓存技术,如 Hazelcast 或 Redis,而不是 in-memory 缓存。这样从技术上讲,缓存数据的一致性将由缓存提供程序来保证。
我还想向您推荐 This tutorial - 演讲者谈到了缓存实现的不同方面,我认为它与您的问题非常相关。