【发布时间】:2019-09-27 06:25:42
【问题描述】:
我有一个 EE 应用程序,我想将其部署到集群中的 2 个 wildfly13 实例。我有一个使用@Cache(来自休眠)和@NamedQuery的实体,并提示使用缓存:可以通过id(将使用@Cache)和其他查询(在这种情况下使用查询提示)查询实体.
用于提示的缓存区域是“replicated-query”。 我使用wildfly 13,所以我有hibernate 5.1.14(非ee 8预览模式),infinispan 9.2.4和jgroups 4.0.11和java 10(我们不能去java 11,因为我们仍然在Unsafe类中删除了一些内容有依赖于它的库)。 该应用程序包含 100 多个 EJB 和接近 150k LOC,因此升级 wildfly 暂时不是一个选项。
问题是:复制的缓存没有复制,甚至没有以复制的方式开始。
Infinispan replicated cache not replicating objects for read 没有帮助,Replicated infinispan cache with Wildfly 11 也没有帮助。
我将 jgroups 与 tcpping 一起使用(因为应用程序将部署在私有云上,我们需要保持网络尽可能低,因此 udp 不是一个选项)。集群在 2 个 wildfly 实例之间形成良好(由日志和 jmx 确认),但是复制的缓存在部署时没有启动,就好像它找不到传输一样。
我用于类型“replicated-cache”的缓存名称没有任何区别,包括预配置的“replicated-query”。
使用 Paul Ferraro here 提到的 jgroups 的“不推荐使用的配置”,不允许集群形成(在我的情况下是退一步,因为使用我的 conf 时集群正在形成)。
一件奇怪的事情是:配置为已复制的 UpdateTimestamp 缓存正在复制(由日志和 jmx 确认:区域名称以 repl_async 为后缀)。
缓存默认处于 invalidation_sync 状态,并且工作正常,因为 sql 查询仅使用相同的参数发出一次(由日志和统计信息确认)。
目前(测试/调试目的),我将两个实例都部署在本地。 omega1 的端口偏移量为 20000,omega2 的端口偏移量为 30000。
我没有尝试过分布式缓存,因为根据我的阅读,我会遇到同样的问题。
这里是实体的相关部分:
@Entity
@Table(name = "my_entity", schema = "public")
@NamedQueries({
@NamedQuery(name = "myEntityTest", query = "select p from MyEntity p where p.value = :val", hints = {
@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"),
@QueryHint(name = org.hibernate.annotations.QueryHints.CACHE_REGION, value = "RPL-myEntityTest")
})
})
@Cache(usage = CacheConcurrencyStrategy.NONE, region = "replicated-entity")
这是standalone-full-ha.xml的jgroups子系统部分:
<subsystem xmlns="urn:jboss:domain:jgroups:6.0">
<channels default="omega-ee">
<channel name="omega-ee" stack="tcpping" cluster="omega-ejb" statistics-enabled="true"/>
</channels>
<stacks>
<stack name="tcpping">
<transport type="TCP" statistics-enabled="true" socket-binding="jgroups-tcp"/>
<protocol type="org.jgroups.protocols.TCPPING">
<property name="port_range">
10
</property>
<property name="discovery_rsp_expiry_time">
3000
</property>
<property name="send_cache_on_join">
true
</property>
<property name="initial_hosts">
localhost[27600],localhost[37600]
</property>
</protocol>
<protocol type="MERGE3"/>
<protocol type="FD_SOCK"/>
<protocol type="FD_ALL"/>
<protocol type="VERIFY_SUSPECT"/>
<protocol type="pbcast.NAKACK2"/>
<protocol type="UNICAST3"/>
<protocol type="pbcast.STABLE"/>
<protocol type="pbcast.GMS"/>
<protocol type="MFC"/>
<protocol type="FRAG2"/>
</stack>
</stacks>
</subsystem>
这是 jgroups-tcp 的套接字绑定:
<socket-binding name="jgroups-tcp" interface="private" port="7600"/>
这是standalone-full-ha.xml的infinispan休眠缓存容器部分:
<cache-container name="hibernate" module="org.infinispan.hibernate-cache">
<transport channel="omega-ee" lock-timeout="60000"/>
<local-cache name="local-query">
<object-memory size="10000"/>
<expiration max-idle="100000"/>
</local-cache>
<invalidation-cache name="entity">
<transaction mode="NON_XA"/>
<object-memory size="10000"/>
<expiration max-idle="100000"/>
</invalidation-cache>
<replicated-cache name="replicated-query">
<transaction mode="NON_XA"/>
</replicated-cache>
<replicated-cache name="RPL-myEntityTest" statistics-enabled="true">
<transaction mode="BATCH"/>
</replicated-cache>
<replicated-cache name="replicated-entity" statistics-enabled="true">
<transaction mode="NONE"/>
</replicated-cache>
</cache-container>
我在 persistence.xml 中设置了以下属性
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL9Dialect"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
我希望:
要在部署时启动的复制缓存(如果在 infinispan 子系统中配置,甚至可能在启动时启动)
缓存数据在读取时在节点之间复制,在更新/过期/失效时在集群范围内失效
要从缓存中检索的数据(本地,因为它应该已被复制)。
我觉得我离预期的结果不远了,但我错过了一些东西。
任何帮助将不胜感激!
更新 1:
我刚刚尝试了@Bela Ban 的建议,并将两个节点上的初始主机设置为localhost[7600],但没有成功:集群没有形成。我使用端口偏移来启动本地机器上的两个节点以避免端口重叠。
在两台主机上都有localhost[7600],一个节点如何知道在哪个端口上连接到另一个,因为我需要使用端口偏移量?
我什至在我从偏移量 20000 开始的节点上尝试了localhost[7600],localhost[37600],在我从偏移量 30000 开始的节点上尝试了localhost[7600],localhost[27600]。集群正在形成,但缓存没有复制。
更新 2: 实体的缓存在 invalidation_sync 并按预期工作,这意味着 jgroups 按预期工作并确认集群结构良好,所以我的猜测是问题与 infinispan 或 wildfly 相关。
【问题讨论】:
-
可能有点傻,但你试过删除
CacheConcurrencyStrategy.NONE吗?还是使用其他任何选项? -
这里的另一件重要事情是弄清楚正在使用哪个 Infinsipan 实例,是由 WildFly 提供的,还是您在部署中提供自己的 Infinispan 版本。对于 Hibernate Cache 用例,建议使用前者。如果使用前者,this example 应该按原样工作。
-
好吧,实体缓存很好并且已经正确失效。 @Cache 注释是否会影响实体缓存以外的某些缓存?如果我不提供 infinispan 的 jar,我会在 org.infinispan.Cache 上收到 NoClassDefFoundError(闻起来像类加载问题,但我似乎没有修复它......
-
也尝试了 CacheConcurrencyStrategy.READ_WRITE,同样的结果。
-
嗨,@will,你解决了这个问题吗?我与会话缓存类似,我认为它没有被复制。
标签: java hibernate wildfly infinispan