2017-05-18 21 views
2

Ich verwende Spring + Hazelcast 3.8.2 und haben eine Karte konfiguriert wie dies die Spring-Konfiguration mit:Hazelcast in der Nähe von Cache: Vertreiben, wenn auf verschiedenen Knoten geändert

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

ich zwei Clients verbunden haben (beide auf derselben Maschine [Test env], verschiedene Ports verwendend).

Wenn ich einen Wert in der Karte auf einem Client ändern noch der andere Kunde hat den alten Wert, bis es aufgrund der abgelaufenen Leerlaufzeit aus dem nahen Cache geräumt bekommen.

fand ich ein ähnliches Problem wie diese hier: Hazelcast near-cache eviction doesn't work

Aber ich bin nicht sicher, ob dies wirklich das gleiche Problem, zumindest wird erwähnt, dass dies ein Fehler in Version 3.7 war und wir 3.8 verwenden. 2.

Ist dies ein korrektes Verhalten oder mache ich etwas falsch? Ich weiß, dass es eine Eigenschaft gibt invalidate-on-change, aber als Standard ist dies true, also erwarte ich nicht, dass ich diesen einstellen muss.

Ich habe auch versucht, die read-backup-data auf false, hilft nicht.

Vielen Dank für Ihre Unterstützung

Christian

Antwort

0

fand ich die Lösung selbst.

Das Problem ist, dass die Hazelcast Ungültigmachungen standardmäßig in den Reihen sendet und so wartet es einige Sekunden, bis die Ungültigkeits wird an alle anderen Knoten gesendet werden.

Sie können weitere Informationen zu diesem finden Sie hier: http://docs.hazelcast.org/docs/3.8/manual/html-single/index.html#near-cache-invalidation

So hatte ich die Eigenschaft hazelcast.map.invalidation.batch.enabled-false einzustellen, die sofort Ungültigmachungen an alle Knoten aussenden. Aber wie in der Dokumentation erwähnt wird, soll dies nur verwendet werden, wenn es nicht zu viele Put/entfernen/... Operationen erwartet, da dies dann das Ereignissystem sehr beschäftigt machen.

Dennoch, obwohl diese Eigenschaft gesetzt ist es garantiert nicht, dass alle Knoten wird direkt die in der Nähe von Cache-Einträge ungültig. Ich bemerkte, dass nach dem direkt die Werte auf dem anderen Knoten Zugriff auf manchmal ist es gut, manchmal nicht. Hier

ist die JUnit-Test ich dafür aufgebaut:

@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 finishs nur manchmal erfolgreich, testWithoutInvalidationBatchEnabled finishs immer erfolgreich.

Verwandte Themen