I'm using a Hazelcast IMap where I update values a lot using an EntryProcessor. At the same time, other threads are calling get(). I would like to avoid all unnecessary deserialization if possible. But it seems that it's still deserializing even when using a single node.
Is there any way to avoid this? I've set the in-memory format of both the Map and near cache to OBJECT. I also set cache-local-entries to true, but still no luck. I'm using Hazelcast 3.12.
Here's my sample code:
public class HazelcastSerializationTest {
static int readCount = 0;
private String mapName = "map1";
private HazelcastInstance createHazelcast() {
Config config = new Config("HazelcastSerializationTest");
config.addMapConfig(new MapConfig(mapName)
.setInMemoryFormat(InMemoryFormat.OBJECT)
.setNearCacheConfig(new NearCacheConfig(mapName)
.setInMemoryFormat(InMemoryFormat.OBJECT)
.setCacheLocalEntries(true)));
config.getNetworkConfig().getJoin()
.getMulticastConfig().setEnabled(false);
return Hazelcast.newHazelcastInstance(config);
}
@Test
public void testEntry() {
HazelcastInstance instance = createHazelcast();
IMap<Integer, DataObject> map = instance.getMap(mapName);
map.put(1, new DataObject(0));
for (int i = 0; i < 100; i++) {
map.executeOnKey(1, new NothingProcessor());
map.get(1);
}
assertEquals(2, readCount);
}
}
class NothingProcessor extends AbstractEntryProcessor<Integer, DataObject> {
@Override
public Object process(Map.Entry<Integer, DataObject> entry) {
entry.setValue(new DataObject(entry.getValue().getValue() + 1));
return null;
}
}
class DataObject implements Externalizable {
private int value;
public DataObject(int value) {
this.value = value;
}
public DataObject() { }
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(value);
}
@Override
public void readExternal(ObjectInput in) throws IOException {
HazelcastSerializationTest.readCount++;
value = in.readInt();
}
}
Am I missing something? I would expect this to just return the real object from the near cache. The deserialization seems unnecessary. I should also mention that in my scenario, the key and value objects are immutable.
When you update an entry through EntryProcessor then it also invalidates the value of the key in NearCache. So whenever you do a get()
on that key, the new value is fetched from the server and stored in NearCache. And fetching from server on a get()
= serialization + deserialisation, regardless of in-memory-format type.