Infinispan集群缓存模式下过期收割器及touch命令相关疑问
当前缓存配置
<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: wakeUpInterval is <= 0, not starting expired purge thread
官方文档相关说明
If you use clustered cache modes, you should never disable the expiration reaper.
此外文档提到:存在touch命令,用于在集群中同步"最近访问"的元数据,但该操作可能影响性能,因为cache.get()请求需等待所有touch命令完成才会返回。而文档下一段又说明"Maximum idle expiration does not work with invalidation mode",这造成了困惑。
疑问解答
1. 若缓存对象永不过期,为何仍需每分钟运行一次收割器线程?能否通过interval="0"禁用它?
当你把max-idle和lifespan都设为-1时,缓存对象确实不会过期,收割器线程没有实际的过期数据需要清理。但官方文档强调集群模式下不能禁用收割器,核心原因是Infinispan的集群缓存逻辑中,收割器线程除了清理过期数据,还会参与集群内缓存状态同步、元数据维护等隐性工作——即便当前没有过期数据,禁用它可能导致部分集群一致性机制无法正常运作。
从实际运行角度看,如果你确认所有缓存都配置了永不过期,设置interval="0"禁用收割器不会引发功能问题,因为确实没有数据需要被收割。但官方不推荐这么做,是为了避免后续修改过期配置后忘记重新启用收割器,导致过期数据堆积。如果不想看到警告,可以把interval设为60000(即1分钟),此时收割器会正常运行,但因为没有过期数据,不会产生额外性能开销。
2. 为何需要touch命令?能否禁用它?是否应至少将touch模式设置为"ASYNC"?
先理清文档的矛盾点:失效模式(invalidation mode)下,max-idle过期本身就不生效。因为失效模式的核心是当某个节点修改数据时,通知其他节点删除对应缓存条目,而非同步访问时间这类元数据。
touch命令的设计初衷是支持分布式/复制模式下的max-idle过期逻辑——这类模式下需要同步所有节点的访问时间,确保各节点的过期判断一致。但在失效模式下,由于max-idle不生效,touch操作完全是多余的。
针对你的场景:
- 可以直接禁用touch命令:去掉多余的性能损耗,毕竟它在失效模式下没有实际作用。
- 如果不想完全禁用,至少要将touch模式设为
ASYNC:这样cache.get()请求不需要等待touch命令在集群内完成,能消除同步touch带来的性能影响。
内容的提问来源于stack exchange,提问作者Janning Vygen

