Hibernate 在集群中使用 infinispan 失效缓存
Hibernate with infinispan invalidation cache in a cluster
我在集群环境中使用 Hibernate 5.4.22 和 Infinispan 11.0.4。 Hibernate 二级缓存配置为使用 JCache 提供程序:
hbProps.setProperty("hibernate.cache.use_minimal_puts", "false");
hbProps.setProperty("hibernate.cache.use_structured_entries", "false");
hbProps.setProperty("hibernate.cache.use_query_cache", "false");
hbProps.setProperty("hibernate.cache.use_second_level_cache", "true");
hbProps.setProperty("hibernate.cache.region.factory_class", "org.hibernate.cache.jcache.JCacheRegionFactory");
hbProps.setProperty("hibernate.javax.cache.provider", "org.infinispan.jcache.embedded.JCachingProvider");
Infinispan 配置如下 infinispan.xml:
<infinispan
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:11.0 http://www.infinispan.org/schemas/infinispan-config-11.0.xsd"
xmlns="urn:infinispan:config:11.0">
<jgroups>
<stack name="jgroups-stack">
<TCP bind_port="7800"
recv_buf_size="${tcp.recv_buf_size:130k}"
send_buf_size="${tcp.send_buf_size:130k}"
max_bundle_size="64K"
sock_conn_timeout="300"
thread_pool.min_threads="0"
thread_pool.max_threads="20"
thread_pool.keep_alive_time="30000"/>
<!-- <TCPPING async_discovery="true"
initial_hosts="${jgroups.tcpping.initial_hosts:localhost[7800],localhost[7801]}"
port_range="2"/>-->
<MPING/>
<MERGE3 min_interval="10000"
max_interval="30000"/>
<FD_SOCK/>
<FD_ALL timeout="9000" interval="3000" />
<VERIFY_SUSPECT timeout="1500" />
<BARRIER />
<pbcast.NAKACK2 use_mcast_xmit="false"
discard_delivered_msgs="true"/>
<UNICAST3 />
<pbcast.STABLE desired_avg_gossip="50000"
max_bytes="4M"/>
<pbcast.GMS print_local_addr="false" join_timeout="2000"/>
<UFC max_credits="2M"
min_threshold="0.4"/>
<MFC max_credits="2M"
min_threshold="0.4"/>
<FRAG2 frag_size="60K" />
<!--RSVP resend_interval="2000" timeout="10000"/-->
<pbcast.STATE_TRANSFER/>
</stack>
</jgroups>
<cache-container>
<!-- turn off metrics -->
<metrics gauges="false" histograms="false"/>
<jmx enabled="true"/>
<transport stack="jgroups-stack" cluster="infinispan-hibernate-cluster"/>
<serialization marshaller="org.infinispan.commons.marshall.JavaSerializationMarshaller">
<white-list>
<regex>.*</regex>
</white-list>
</serialization>
<!-- <replicated-cache name="MainCache" mode="SYNC">
<memory max-count="100000"/>
<expiration max-idle="3600000" lifespan="-1"/>
</replicated-cache>-->
<invalidation-cache name="MainCache" mode="SYNC">
<memory max-count="100000"/>
<expiration max-idle="3600000" lifespan="-1"/>
</invalidation-cache>
</cache-container>
</infinispan>
我有一个测试实体 'Profile' 应该使用 read-write
策略进行缓存:
<hibernate-mapping>
<class name="hibernatetest.Profile" table="Profiles" lazy="false">
<cache usage="read-write" region="MainCache"/>
<id column="id" name="id" unsaved-value="0">
<generator class="native"/>
</id>
<discriminator column="type" type="string"/>
<version name="version"/>
<property name="name" type="string" length="100"/>
<property name="available" type="yes_no"/>
</class>
</hibernate-mapping>
根据Cache concurrency strategy/cache mode compatibility table,<cache usage="read-write">
和<invalidation-cache>
的组合应该是一个工作场景。在我的测试中,我有一个持续读取对象的节点和一个更新同一对象的节点。我发现读取节点永远不会收到对象已更改的通知,以便从数据库中再次读取它。看日志,好像写节点上的失效缓存没有向读节点发送任何消息。
但是,如果我将 infinispan.xml 更改为使用 <replicated-cache>
或 <distributed-cache>
而不是 <invalidation-cache>
,则读取节点会收到写入节点所做的更改通知.所以,我想这意味着问题不在 jgroups 中。
这是失效缓存中的问题,还是我的配置中遗漏了什么?
这是从失效缓存中读取的实例的日志文件inv-read.txt and a log file of the instance that updates the cache inv-update.txt。
谢谢!
问题在于使用 JCache - table 假定 InfinispanRegionFactory 而不是 JCacheRegionFactory。
Infinispan 似乎没有明确支持 Hibernate 5.4 的模块 - 我猜想 modules to support Hibernate 5.3 即使在 Hibernate 5.4 中也应该可以工作,不过,因为 second-level-cache 登陆 Hibernate 5.4。
我很惊讶 2LC 与 JCache 一起使用 replicated/distributed 缓存 - 我很确定它不起作用 'reliably'(事务性,涵盖边缘情况等)无论如何。
我在集群环境中使用 Hibernate 5.4.22 和 Infinispan 11.0.4。 Hibernate 二级缓存配置为使用 JCache 提供程序:
hbProps.setProperty("hibernate.cache.use_minimal_puts", "false");
hbProps.setProperty("hibernate.cache.use_structured_entries", "false");
hbProps.setProperty("hibernate.cache.use_query_cache", "false");
hbProps.setProperty("hibernate.cache.use_second_level_cache", "true");
hbProps.setProperty("hibernate.cache.region.factory_class", "org.hibernate.cache.jcache.JCacheRegionFactory");
hbProps.setProperty("hibernate.javax.cache.provider", "org.infinispan.jcache.embedded.JCachingProvider");
Infinispan 配置如下 infinispan.xml:
<infinispan
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:11.0 http://www.infinispan.org/schemas/infinispan-config-11.0.xsd"
xmlns="urn:infinispan:config:11.0">
<jgroups>
<stack name="jgroups-stack">
<TCP bind_port="7800"
recv_buf_size="${tcp.recv_buf_size:130k}"
send_buf_size="${tcp.send_buf_size:130k}"
max_bundle_size="64K"
sock_conn_timeout="300"
thread_pool.min_threads="0"
thread_pool.max_threads="20"
thread_pool.keep_alive_time="30000"/>
<!-- <TCPPING async_discovery="true"
initial_hosts="${jgroups.tcpping.initial_hosts:localhost[7800],localhost[7801]}"
port_range="2"/>-->
<MPING/>
<MERGE3 min_interval="10000"
max_interval="30000"/>
<FD_SOCK/>
<FD_ALL timeout="9000" interval="3000" />
<VERIFY_SUSPECT timeout="1500" />
<BARRIER />
<pbcast.NAKACK2 use_mcast_xmit="false"
discard_delivered_msgs="true"/>
<UNICAST3 />
<pbcast.STABLE desired_avg_gossip="50000"
max_bytes="4M"/>
<pbcast.GMS print_local_addr="false" join_timeout="2000"/>
<UFC max_credits="2M"
min_threshold="0.4"/>
<MFC max_credits="2M"
min_threshold="0.4"/>
<FRAG2 frag_size="60K" />
<!--RSVP resend_interval="2000" timeout="10000"/-->
<pbcast.STATE_TRANSFER/>
</stack>
</jgroups>
<cache-container>
<!-- turn off metrics -->
<metrics gauges="false" histograms="false"/>
<jmx enabled="true"/>
<transport stack="jgroups-stack" cluster="infinispan-hibernate-cluster"/>
<serialization marshaller="org.infinispan.commons.marshall.JavaSerializationMarshaller">
<white-list>
<regex>.*</regex>
</white-list>
</serialization>
<!-- <replicated-cache name="MainCache" mode="SYNC">
<memory max-count="100000"/>
<expiration max-idle="3600000" lifespan="-1"/>
</replicated-cache>-->
<invalidation-cache name="MainCache" mode="SYNC">
<memory max-count="100000"/>
<expiration max-idle="3600000" lifespan="-1"/>
</invalidation-cache>
</cache-container>
</infinispan>
我有一个测试实体 'Profile' 应该使用 read-write
策略进行缓存:
<hibernate-mapping>
<class name="hibernatetest.Profile" table="Profiles" lazy="false">
<cache usage="read-write" region="MainCache"/>
<id column="id" name="id" unsaved-value="0">
<generator class="native"/>
</id>
<discriminator column="type" type="string"/>
<version name="version"/>
<property name="name" type="string" length="100"/>
<property name="available" type="yes_no"/>
</class>
</hibernate-mapping>
根据Cache concurrency strategy/cache mode compatibility table,<cache usage="read-write">
和<invalidation-cache>
的组合应该是一个工作场景。在我的测试中,我有一个持续读取对象的节点和一个更新同一对象的节点。我发现读取节点永远不会收到对象已更改的通知,以便从数据库中再次读取它。看日志,好像写节点上的失效缓存没有向读节点发送任何消息。
但是,如果我将 infinispan.xml 更改为使用 <replicated-cache>
或 <distributed-cache>
而不是 <invalidation-cache>
,则读取节点会收到写入节点所做的更改通知.所以,我想这意味着问题不在 jgroups 中。
这是失效缓存中的问题,还是我的配置中遗漏了什么?
这是从失效缓存中读取的实例的日志文件inv-read.txt and a log file of the instance that updates the cache inv-update.txt。
谢谢!
问题在于使用 JCache - table 假定 InfinispanRegionFactory 而不是 JCacheRegionFactory。
Infinispan 似乎没有明确支持 Hibernate 5.4 的模块 - 我猜想 modules to support Hibernate 5.3 即使在 Hibernate 5.4 中也应该可以工作,不过,因为 second-level-cache 登陆 Hibernate 5.4。
我很惊讶 2LC 与 JCache 一起使用 replicated/distributed 缓存 - 我很确定它不起作用 'reliably'(事务性,涵盖边缘情况等)无论如何。