我使用Spring + Hazelcast 3.8.2,并使用Spring配置配置了这样的映射:
<hz:map name="test.*" backup-count="1"
max-size="0" eviction-percentage="30" read-backup-data="true"
time-to-live-seconds="900"
eviction-policy="NONE" merge-policy="com.hazelcast.map.merge.PassThroughMergePolicy">
<hz:near-cache max-idle-seconds="300"
time-to-live-seconds="0"
max-size="0" />
</hz:map>我已经连接了两个客户机(都在同一台机器上测试env,使用不同的端口)。
当我在一个客户端上更改映射中的值时,另一个客户端仍然具有旧的值,直到由于过期的空闲时间而从近缓存中被逐出。
我在这里发现了一个类似的问题:Hazelcast near-cache eviction doesn't work
但我不确定这是否真的是同样的问题,至少有人提到这是3.7版中的一个bug,我们使用的是3.8.2。
这是正确的行为还是我做错了什么?我知道有一个属性invalidate-on-change,但是默认情况下这是true,所以我不需要设置这个属性。
我还尝试将read-backup-data设置为false,但没有帮助。
多谢你们的支持
克里斯蒂安
发布于 2017-05-19 10:17:45
我自己找到了解决办法。
问题是,Hazelcast在默认情况下以批方式发送失效,因此它等待几秒钟,直到失效被发送到所有其他节点。
您可以在这里找到更多有关这方面的信息:http://docs.hazelcast.org/docs/3.8/manual/html-single/index.html#near-cache-invalidation
因此,我必须将属性hazelcast.map.invalidation.batch.enabled设置为false,这将立即向所有节点发送无效信息。但是,正如文档中提到的,只有在没有太多put/remove/.操作预期,因为这将使事件系统非常繁忙。
然而,即使设置了该属性,也不能保证所有节点都将直接使近缓存项失效。我注意到,在直接访问不同节点上的值之后,有时会很好,有时不会。
下面是我为此构建的JUnit测试:
@Test
public void testWithInvalidationBatchEnabled() throws Exception {
System.setProperty("hazelcast.map.invalidation.batch.enabled", "true");
doTest();
}
@Test
public void testWithoutInvalidationBatchEnabled() throws Exception {
System.setProperty("hazelcast.map.invalidation.batch.enabled", "false");
doTest();
}
@After
public void shutdownNodes() {
Hazelcast.shutdownAll();
}
protected void doTest() throws Exception {
// first config for normal cluster member
Config c1 = new Config();
c1.getNetworkConfig().setPort(5709);
// second config for super client
Config c2 = new Config();
c2.getNetworkConfig().setPort(5710);
// map config is the same for both nodes
MapConfig testMapCfg = new MapConfig("test");
NearCacheConfig ncc = new NearCacheConfig();
ncc.setTimeToLiveSeconds(10);
testMapCfg.setNearCacheConfig(ncc);
c1.addMapConfig(testMapCfg);
c2.addMapConfig(testMapCfg);
// start instances
HazelcastInstance h1 = Hazelcast.newHazelcastInstance(c1);
HazelcastInstance h2 = Hazelcast.newHazelcastInstance(c2);
IMap<Object, Object> mapH1 = h1.getMap("test");
IMap<Object, Object> mapH2 = h2.getMap("test");
// initial filling
mapH1.put("a", -1);
assertEquals(mapH1.get("a"), -1);
assertEquals(mapH2.get("a"), -1);
int updatedH1 = 0, updatedH2 = 0, runs = 0;
for (int i = 0; i < 5; i++) {
mapH1.put("a", i);
// without this short sleep sometimes the nearcache is updated in time, sometimes not
Thread.sleep(100);
runs++;
if (mapH1.get("a").equals(i)) {
updatedH1++;
}
if (mapH2.get("a").equals(i)) {
updatedH2++;
}
}
assertEquals(runs, updatedH1);
assertEquals(runs, updatedH2);
}testWithInvalidationBatchEnabled只在有时成功,testWithoutInvalidationBatchEnabled总是成功。
https://stackoverflow.com/questions/44053445
复制相似问题