Cayenne Cache - 查询缓存是否取代对象缓存?

Cayenne Cache - Does Query Cache Replace object Cache?

我正在寻找有关如何在集群中 运行ning 或使用同一域的多个 JVM 时最佳配置 cayenne 的资源。我一直在阅读文档,我看到了这个:

"there are ways to notify other stacks about the object changes. This can be set up in the Modeler. However full synchronization of every change often results in excessive network traffic and CPU consumption, and is usually avoided in favor of the query cache approach described elsewhere in this chapter."

链接到查询结果缓存页面。据我了解,当通过 getter 检索关联对象或通过其 ID 检索对象时,将使用对象缓存。这句话是否告诉我,如果我配置查询缓存,将不会使用对象缓存?或者我需要避免这样做会命中我的应用程序代码中的对象缓存?我是否应该完全禁用对象缓存(如果可能的话)?如果我不设置 cayenne 来通知其他堆栈对象缓存的更改,我不会 运行 有过时数据的风险吗?

我很感激关于跨多个节点 运行 cayenne 的最佳方式的所有提示,或者如果您有一些资源可以指导我,那也会非常有帮助。

提前感谢您的宝贵时间!

对象缓存和查询缓存相互独立,但它们会影响彼此的状态。

对象缓存

扩展对象图时访问对象缓存(正如您正确注意到的那样)。但是object cache的synchronization不只是更新cache,还会传播到ObjectContexts,引起in-memory object graph的刷新。虽然这听起来很棒并且超级自动化,但根据经验,当您拥有与单个用户相关的有限对象图时,它在桌面应用程序中最有用。在集群的多用户 Web 应用程序中,同步对象缓存更多的是麻烦而不是帮助。它会产生大量网络流量,迫使您的实例消耗 CPU 来处理它们并不真正关心的事件,最后,在您最不期望的时候从底层更新您的对象。所以我通常关闭对象缓存同步,完全依赖集群查询缓存来处理同步。

查询缓存

这里 an example project 演示了带集群的查询缓存。它使用 Cayenne 4.0,EHCache 作为缓存提供程序,ActiveMQ/JMS 用于跨实例事件。

查询缓存的工作方式,它缓存与给定查询匹配的对象列表,如果查询包含预取,则包括预取的相关对象。要充分利用查询缓存,您可能需要稍微改变一下编码风格。无需在实例变量中存储对查询结果列表的长期引用(本质上是进行自己的缓存),而是在需要此类列表时随时创建 运行 查询(具有适当的缓存设置),并让 Cayenne 决定列表应该从缓存中返回还是从数据库中获取。

下一步是以某种方式配置您的缓存,具体取决于您使用的提供程序来指定其默认过期策略(每个缓存组)。例如。 sample EHCache config.

最后,您可以添加集群和事件驱动的缓存刷新,这可以通过 API 调用显式完成,也可以在提交某些实体时隐式完成(仅自 Cayenne 3.1 起可用)。

查询缓存刷新非常便宜。通过网络发送的唯一内容是 "cache group" 的名称,在接收端,一堆列表立即被懒惰地失效。它还会产生更清晰的代码。

如果您主要依赖查询缓存,则不需要 "turn off" 对象缓存本身。对象缓存是 Cayenne 不可或缺的一部分,许多操作(更新、关系处理)都需要它。它会在您 运行 查询时自动更新。不过,您通常需要做的是关闭自动对象刷新。通过不启用对象缓存集群,您已经避免了跨 JVM 同步。此外,您可以使用 this advice 在同一 VM 中禁用跨 ObjectContext 同步。

卡宴版

我强烈建议至少升级到 Cayenne 3.1(甚至升级到 4.0.M2)。除了其他优点之外,缓存机制比 3.0 更成熟。这将使您在配置 Cayenne 和集成外部缓存提供程序时变得更加轻松。