我正在寻找有关如何在群集中运行时最佳配置cayenne或使用相同域的多个JVM的资源。我一直在阅读文档,我看到了:
"有办法通知其他堆栈有关对象的更改。这可以在Modeler中设置。但是,每次更改的完全同步通常会导致过多的网络流量和CPU消耗,并且通常会避免使用本章其他地方描述的查询缓存方法。"
链接到Query-Result-Caching页面。我的理解是,当通过getter检索关联对象或通过其id检索对象时,使用对象缓存。这句话告诉我,如果我配置查询缓存,对象缓存不会被使用吗?或者我需要避免这样做会在我的应用程序代码中击中对象缓存?我应该完全禁用对象缓存(如果可能的话)?如果我没有设置cayenne来通知对象缓存的其他堆栈更改,那么我是否存在过时数据的风险?
我非常欣赏有关在多个节点上运行cayenne的最佳方法的任何提示,或者如果您有一些资源可以指向我,那将非常有用。
提前感谢您的时间!
答案 0 :(得分:1)
对象缓存和查询缓存彼此独立,但它们可以影响彼此的状态。
对象缓存
扩展对象图时访问对象缓存(正如您所注意到的)。但是,对象缓存的同步不仅会更新缓存,还会传播到ObjectContexts,从而导致刷新内存中的对象图。虽然这听起来很棒且超级自动,但从体验来看,当您拥有与单个用户相关的有限对象图时,它在桌面应用程序中最有用。在集群的多用户Web应用程序中,同步对象缓存更令人讨厌,然后提供帮助。它会创建大量网络流量,迫使您的实例使用CPU来处理他们并不真正关心的事件,最后,当您最不期望它时,从下面更新您的对象。所以我通常会关闭对象缓存同步,并完全依赖集群查询缓存来处理同步。
查询缓存
以下an example project演示了具有群集的查询缓存。它使用Cayenne 4.0,EHCache作为缓存提供程序,使用ActiveMQ / JMS进行跨实例事件。
查询缓存的工作方式,它缓存与给定查询匹配的对象列表,包括查询包含预取的预取相关对象。要充分利用查询缓存,您可能需要稍微更改编码样式。您可以在需要此类列表的任何时候创建并运行查询(具有适当的缓存设置),而不是在您的实例变量中存储对查询结果列表的长期引用(基本上是执行您自己的缓存),并让Cayenne决定列表是否应该从缓存返回或从DB中获取新鲜内容。
下一步是以某种方式配置缓存,具体取决于您使用的提供程序来指定其默认过期策略(每个缓存组)。例如。一个sample EHCache config。
最后,您可以添加群集和事件驱动的缓存刷新,这可以通过API调用显式执行,也可以在某些实体的提交时隐式执行(仅在Cayenne 3.1之后可用)。
查询缓存刷新非常便宜。通过网络发送的唯一内容是“缓存组”的名称,并且在接收端,一堆列表一下子懒得无效。它还可以使代码更清晰。
如果您主要依赖查询缓存,则不需要“关闭”对象缓存本身。对象缓存是Cayenne不可或缺的一部分,是许多操作(更新,关系处理)所必需的。它将在您运行查询时自动更新。您通常需要做的是关闭自动对象刷新。通过不启用对象缓存群集,您已经避免了跨JVM同步。此外,您可以使用this advice禁用同一VM中的跨ObjectContext同步。
Cayenne版本
我强烈建议至少升级到Cayenne 3.1(甚至升级到4.0.M2)。除了其他好处之外,缓存机制比3.0更成熟。它将使您在配置Cayenne和集成外部缓存提供商方面的体验变得更加轻松。