Ignite - полная синхронизация - PullRequest
0 голосов
/ 24 мая 2018

У меня есть два узла воспламенения сервера (каждый узел запускается в приложении Spring Boot) в кластере.

И у меня есть два кеша:

// Стойкость Cahce

configuration.setReadThrough(true);
    configuration.setWriteThrough(true);
    configuration.setCacheStoreFactory(storeFactory);
    configuration.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
    configuration.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
    configuration.setCacheMode(CacheMode.REPLICATED);

// в памяти

configuration.setIndexedTypes(String.class, SequenceReserve.class);
    configuration.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
    configuration.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
    configuration.setCacheMode(CacheMode.REPLICATED);

Запросы на обновление любых кэшей могут отправляться на каждый узел параллельно.

Каждое обновление - атомарная операция.

cache.invoke(...);

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

Любой узел должен вернуть исключение, если транзакция не была зафиксирована на всех узлах.

Могу ли я написать такую ​​конфигурацию, чтобы такое поведение гарантировалось с вероятностью 100%.

ОБНОВЛЕНО

Я выполнил тест и получил следующее поведение:

Каждый запрос всегда выполняется на одном и том же узле (метод invoke).Я считаю, что это правильное поведение.Когда запрос будет выполнен на втором узле?

1 Ответ

0 голосов
/ 24 мая 2018

IgniteCache # invoke (...) - это транзакционная операция.Лучший способ узнать это - проверить, генерирует ли оно TransactionException.

Ваша конфигурация кажется достаточной для обеспечения согласованности данных между узлами.

Если вы имеете в виду согласованность между этими двумя кэшами, то выможет запускать явные транзакции и запускать invoke -s внутри них.

UPD

Обратите внимание, что, как упоминалось в JavaDoc для invoke(..) метод, ваш EntryProcessor должен быть без сохранения состояния.Он может вызываться несколько раз на разных узлах, поэтому он должен возвращать одно и то же значение каждый раз.

UPD 2

Если вы вызываете метод IgniteCache#invoke() для транзакциикеш, он заставляет EntryProcessor вызываться на каждом узле, который содержит необходимый раздел этого кеша.Но если кэш атомарный, то EntryProcessor будет вызываться только на основном узле.

Но вы не должны полагаться на это поведение.Он нигде не указан, поэтому может измениться в будущих версиях.Ignite может совершать столько звонков на EntryProcessor#process(), сколько необходимо для обеспечения согласованности данных.

Вы можете использовать следующий код для проверки моих слов:

public static void main(String[] args) throws IgniteException {
    Ignite ignite = Ignition.start("examples/config/example-ignite.xml");

    IgniteCache<Integer, String> atomicCache = ignite.getOrCreateCache(
        cacheConfiguration("atomic", CacheAtomicityMode.ATOMIC));

    IgniteCache<Integer, String> txCache = ignite.getOrCreateCache(
        cacheConfiguration("transactional", CacheAtomicityMode.TRANSACTIONAL));

    atomicCache.invoke(1, (entry, arguments) -> {
        System.out.println("Atomic invoke");
        return null;
    });

    txCache.invoke(1, (entry, arguments) -> {
        System.out.println("Transactional invoke");
        return null;
    });
}

private static <K, V> CacheConfiguration<K, V> cacheConfiguration(String name, CacheAtomicityMode atomicity) {
    CacheConfiguration<K, V> cacheCfg = new CacheConfiguration<>(name);
    cacheCfg.setAtomicityMode(atomicity);
    cacheCfg.setCacheMode(CacheMode.REPLICATED);
    cacheCfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);

    return cacheCfg;
}

"Транзакционный вызов"будет напечатан на каждом узле, но «Атомный вызов» - только на одном.

...