我们使用 infinispan 作为 hibernate 中的二级缓存。这是我们大多数实体的缓存配置:
<invalidation-cache-configuration
name="entity"
mode="ASYNC">
<encoding media-type="application/x-java-object"/>
<locking concurrency-level="1000" acquire-timeout="1000"/>
<transaction mode="NONE"/>
<expiration max-idle="-1" interval="0" lifespan="-1" />
<memory max-count="2000000"/>
</invalidation-cache-configuration>
它给出了很多警告:
ISPN000025:唤醒间隔为 <= 0, not starting expired purge thread
在文档中说:
如果您使用集群缓存模式,则永远不应该禁用 过期收割者。
另外,文档说有一个“touch”命令,可以同步集群中“最近访问的”元数据。
这可能会降低性能,因为“在所有触摸命令完成之前,cache.get() 请求不会返回”。文档的下一段说:“最大空闲到期时间不适用于失效模式。”所以我很困惑。
我想知道:
如果对象永远不会过期,为什么我们需要每分钟运行一个收割者线程?我可以通过间隔=“0”来禁用它吗?
为什么我们需要触摸命令?我可以禁用它吗?我应该至少将触摸模式设置为“异步”吗?
它给出了很多警告:
ISPN000025:唤醒间隔为 <= 0, not starting expired purge thread
这是一条低于 WARN 级别的 INFO 级别消息。您看到很多的原因是因为它为每个像这样配置的缓存打印一次消息。如果您愿意,可以按原样保留配置并忽略 INFO 消息,它们是启动时的一次性事件。
- 如果对象永远不会过期,为什么我们需要每分钟运行一个收割者线程?我可以通过间隔=“0”来禁用它吗?
是的,可以。请注意,从 Infinispan 的角度来看,我们无法判断对象是否永远不会过期,因为我们还允许以编程方式覆盖写入可以在运行时提供过期的操作。 INFO 消息只是告诉用户“嘿,我们不会自动拾取过期条目,仅在访问时”
- 为什么我们需要触摸命令?我可以禁用它吗?我应该至少将触摸模式设置为“异步”吗?
我认为您可能已经合并了各个部分。 touch命令仅在使用max-idle过期时使用,lifespan过期不使用touch命令。 touch 命令不与您的用例一起使用,不会过期。
touch 命令需要最大空闲,因为当在一个节点上完成读取时,其他所有者不会知道已完成,因此我们必须发送这些 touch 命令来告诉其他所有者节点,这样他们就不会知道不认为该条目实际上已过期。
文档的下一段说:“最大空闲到期时间不适用于失效模式。”
集群最大空闲不能与失效缓存一起使用,因为它破坏了失效的主要优点。通常,应用程序会在同一事务中更新数据库并使缓存无效,因此通常不需要最大空闲值。集群最大空闲时间必须在每次读取时向集群中的所有节点发送 touch 命令,从而增加了开销。
非集群最大空闲可以与失效缓存一起使用,但这并没有要求afaik。如果您愿意,也可以在 https://issues.redhat.com/browse/ISPN 创建新功能。