Получить Hazelcast, чтобы остановить десериализацию объектов при использовании EntryProcessor - PullRequest
2 голосов
/ 01 февраля 2020

Я использую Hazelcast IMap, где я много обновляю значения, используя EntryProcessor. В то же время другие потоки вызывают get (). Я хотел бы избежать всей ненужной десериализации, если это возможно. Но кажется, что он все еще десериализуется даже при использовании одного узла.

Есть ли способ избежать этого? Я установил формат в памяти карты и ближнего кеша для OBJECT. Я также установил для cache-local-records значение true, но все равно не повезло. Я использую Hazelcast 3.12.

Вот мой пример кода:

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();
    }
}

Я что-то упустил? Я ожидал бы, что это просто вернет реальный объект из ближайшего кеша. Десериализация кажется ненужной. Следует также отметить, что в моем сценарии объекты ключа и значения являются неизменяемыми.

1 Ответ

1 голос
/ 06 февраля 2020

Когда вы обновляете запись через EntryProcessor, она также делает недействительным значение ключа в NearCache. Поэтому, когда вы делаете get() для этого ключа, новое значение выбирается с сервера и сохраняется в NearCache. И выборка с сервера при get() = сериализации + десериализации, независимо от типа формата в памяти.

...