【问题标题】:Why infinispan replicated cache isn't replicating?为什么 infinispan 复制缓存不复制?
【发布时间】: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>

我希望:

  1. 要在部署时启动的复制缓存(如果在 infinispan 子系统中配置,甚至可能在启动时启动)

  2. 缓存数据在读取时在节点之间复制,在更新/过期/失效时在集群范围内失效

  3. 要从缓存中检索的数据(本地,因为它应该已被复制)。

我觉得我离预期的结果不远了,但我错过了一些东西。

任何帮助将不胜感激!

更新 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


【解决方案1】:

如果您使用端口 7600(在 jgroups-tcp.xml 中),那么列出端口 27600 和 37600 将不起作用:localhost[27600],localhost[37600] 应该是 localhost[7600]

【讨论】:

  • 我刚刚尝试了您的建议,但没有形成集群。我在本地启动两个wildfly,端口偏移量为:第一个为20000,第二个为30000。那么一个实例如何知道它应该尝试连接到另一个实例的哪个端口呢?
  • 我会从 100 的偏移量开始(如果你在同一个系统上运行),然后是一个普通的 Wildfly,只是改变了 UDP->TCP。如果您部署一个简单的 EJB 或 Web 分布式应用程序,集群应该启动并且两个节点应该形成一个集群(两个节点都需要有应用程序!)initial_hosts 应该有两个服务器具有正确的 ip[port]
  • 这也无济于事。我的初始设置允许形成 jgroups 集群(ejb 缓存是分布式的),但是休眠复制缓存没有复制。
【解决方案2】:

除了纠正其他答案中指示的端口外,我认为您的&lt;cache-container&gt; 中还需要&lt;global-state/&gt;,例如:

       <cache-container name="hibernate" module="org.infinispan.hibernate-cache">
            <transport channel="omega-ee" lock-timeout="60000"/>
            <global-state/>
            <local-cache name="local-query">
                <object-memory size="10000"/>
       ...etc...

【讨论】:

  • Wildfly 不是以此开头的。我没有在服务器模式下使用 infinispan,我使用的是 wildfly 提供的。
  • 这项工作无需触碰 WildFly 提供的缓存容器配置。
猜你喜欢
  • 2018-08-09
  • 2018-06-12
  • 2021-08-01
  • 2020-06-06
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2014-09-13
  • 1970-01-01
相关资源
最近更新 更多