Почему Hazelcast Near Cache не синхронизирован с EntryUpdatedListener, даже если они находятся в одном процессе? - PullRequest
0 голосов
/ 20 июня 2019

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

Однако я ожидаю, что он будет синхронизирован с EntryUpdatedListener, который находится на том же узле и, следовательно, тот же процесс - или я что-то упустил?

Последовательность событий:

Кластер из 1 узла изменяет тот же ключ / значение, переключая значение с X на Y и обратно на X с интервалом каждые X секунд.

Клиент подключается к этому узлу кластера и добавляет EntryUpdatedListener для наблюдения значения переворачивания.

Клиент получает EntryUpdatedEvent и печатает заданное значение - как и ожидалось, он возвращает недавно установленное значение.

Клиент немедленно создает map.get для того же ключа (который должен попасть в ближайший кеш) и печатает значение STALE.

Я нахожу это странным - это означает, что два "канала" в одном и том же клиентском процессе показывают несовместимые версии данных. Я ожидал бы этого только между разными процессами.

Ниже код моего репродуктора:

public class ClusterTest {
    private static final int OLD_VALUE = 10000;
    private static final int NEW_VALUE = 88888;
    private static final int KEY = 5;
    private static final int NUMBER_OF_ENTRIES = 10;

    public static void main(String[] args) throws Exception {
        HazelcastInstance instance = Hazelcast.newHazelcastInstance();

        IMap map = instance.getMap("test");
        for (int i = 0; i < NUMBER_OF_ENTRIES; i++) {
            map.put(i, 0);
        }

        System.out.println("Size of map = " + map.size());

        boolean flag = false;

        while(true) {
            int value = flag ? OLD_VALUE : NEW_VALUE;
            flag = !flag;

            map.put(KEY, value);

            System.out.println("Set a value of [" + value + "]: ");

            Thread.sleep(1000);
        }
    }
}

public class ClientTest {
    public static void main(String[] args) throws InterruptedException {
        HazelcastInstance instance = HazelcastClient.newHazelcastClient(new ClientConfig().addNearCacheConfig(new NearCacheConfig("test")));
        IMap map = instance.getMap("test");
        System.out.println("Size of map = " + map.size());

        map.addEntryListener(new MyEntryListener(instance), true);

        new CountDownLatch(1).await();
    }

    static class MyEntryListener
            implements EntryAddedListener,
            EntryUpdatedListener,
            EntryRemovedListener {
        private HazelcastInstance instance;

        public MyEntryListener(HazelcastInstance instance) {
            this.instance = instance;
        }

        @Override
        public void entryAdded(EntryEvent event) {
            System.out.println("Entry Added:" + event);
        }

        @Override
        public void entryRemoved(EntryEvent event) {
            System.out.println("Entry Removed:" + event);
        }

        @Override
        public void entryUpdated(EntryEvent event) {
            Object o = instance.getMap("test").get(event.getKey());
            boolean equals = o.equals(event.getValue());
            String s = "Event matches what has been fetched = " + equals;

            if (!equals) {
                s += ", EntryEvent value has delivered: " + (event.getValue()) + ", and an explicit GET has delivered:" + o;
            }

            System.out.println(s);
        }
    }
}

Выход от клиента:

INFO: hz.client_0 [dev] [3.11.1] HazelcastClient 3.11.1 (20181218 - d294f31) is CLIENT_CONNECTED
Jun 20, 2019 4:58:15 PM com.hazelcast.internal.diagnostics.Diagnostics
INFO: hz.client_0 [dev] [3.11.1] Diagnostics disabled. To enable add -Dhazelcast.diagnostics.enabled=true to the JVM arguments.
Size of map = 10
Event matches what has been fetched = true
Event matches what has been fetched = false, EntryEvent value has delivered: 88888, and an explicit GET has delivered:10000
Event matches what has been fetched = true
Event matches what has been fetched = true
Event matches what has been fetched = false, EntryEvent value has delivered: 10000, and an explicit GET has delivered:88888

1 Ответ

0 голосов
/ 02 июля 2019

Near Cache имеет гарантию согласованности, в то время как слушатели работают в огне и забывают. Вот почему есть два разных механизма для обоих. Кроме того, пакетирование для событий, близких к кешу, уменьшает сетевой трафик и делает систему событий менее загруженной (это помогает, когда слишком много недействительных или клиентов), в качестве компромисса это может увеличить задержку отдельных недействительных действий. Если вы уверены, что ваша система может обрабатывать каждое событие аннулирования, вы можете отключить пакетирование.

Необходимо настроить свойство на стороне участника, так как события генерируются на элементах кластера и отправляются клиентам.

...