Политика потери партиций (Partition Loss Policy)#

На протяжении жизненного цикла кластера возможны ситуации с недоступностью некоторых партиций из-за сбоев их основных (primary) и резервных (backup) узлов. Такие ситуации могут привести к частичной потере данных — их нужно решать в зависимости от вариантов использования.

Потеря партиции происходит, если ее основная и все резервные копии становятся недоступны кластеру, то есть когда недоступны основной и резервные узлы партиции. Если стали недоступными больше узлов, чем общее количество резервных партиций, произойдет потеря данных. Установить количество резервных партиций для кеша можно в его конфигурации — подробнее написано в разделе «Настройка резервных партиций».

При изменении топологии кластера DataGrid проверяет, не привело ли изменение к потере партиций. После этого в зависимости от настроенной политики потери партиций и базовых параметров автонастройки DataGrid разрешает или запрещает операции с кешами.

Для in-memory-кешей данные при потере партиций можно восстановить только через их повторную загрузку в кластер. В persistent-кешах физической потери данных не происходит, так как они хранятся на диске. После перезапуска кластера узлы, которые отключились или вышли из строя, возвращаются в кластер, и данные для них загружаются с диска. Чтобы продолжить использовать данные, восстановите состояние потерянных партиций — подробнее об этом написано ниже в разделе «Обработка потери партиций».

Настройка политики потери партиций#

Описание политик потери партиций:

Политика

Описание

IGNORE

Потеря партиций игнорируется. Кластер обрабатывает потерянные партиции как пустые. При запросе данных из таких партиций кластер возвращает пустые значения, как будто там никогда не было данных.

Политику можно использовать только в in-memory-кластерах, где базовая автонастройка включена с тайм-аутом 0 (значение по умолчанию для таких конфигураций). Во всех остальных конфигурациях (в кластерах, где есть хотя бы один персистентный регион данных) политика IGNORE заменяется на READ_WRITE_SAFE, даже если в конфигурации кеша явно установлена IGNORE

READ_WRITE_SAFE

Использование операций чтения и записи в потерянной партиции кеша приведет к генерации исключений. Можно выполнять чтение и запись в доступных партициях

READ_ONLY_SAFE

Кеш доступен в режиме только для чтения (read-only). Использование операций записи в кеш и чтения из потерянных партиций приведет к генерации исключений. Подробнее об этом написано ниже в разделе «Обработка потери партиций»

Политика потери партиций настраивается отдельно для каждого кеша:

<bean class="org.apache.ignite.configuration.IgniteConfiguration">

    <property name="cacheConfiguration">
        <bean class="org.apache.ignite.configuration.CacheConfiguration">
            <property name="name" value="myCache"/>

            <property name="partitionLossPolicy" value="READ_ONLY_SAFE"/>
        </bean>
    </property>
    <!-- Другие свойства. -->

</bean>
CacheConfiguration cacheCfg = new CacheConfiguration("myCache");

cacheCfg.setPartitionLossPolicy(PartitionLossPolicy.READ_ONLY_SAFE);

Прослушивание событий потери партиций#

Чтобы получать уведомления о потере партиций, настройте прослушивание события EVT_CACHE_REBALANCE_PART_DATA_LOST. Оно вызывается для каждой потерянной партиции и содержит ее номер и информацию об узле, на котором она находится. События активируются только при использовании политики READ_WRITE_SAFE или READ_ONLY_SAFE.

Пример, как включить событие в конфигурации кластера (подробнее об этом написано в подразделе «Включение и прослушивание событий» раздела «Работа с событиями»):

Java#
Ignite ignite = Ignition.start();

IgnitePredicate<Event> locLsnr = evt -> {
    CacheRebalancingEvent cacheEvt = (CacheRebalancingEvent) evt;

    int lostPart = cacheEvt.partition();

    ClusterNode node = cacheEvt.discoveryNode();

    System.out.println(lostPart);

    return true; // Продолжайте прослушивание событий.
};

ignite.events().localListen(locLsnr, EventType.EVT_CACHE_REBALANCE_PART_DATA_LOST);

Подробнее о других событиях ребалансировки партиций написано в подразделе «События» раздела «Работа с событиями».

Обработка потери партиций#

Чтобы продолжить работу с данными при отсутствии их физической потери, верните покинувшие кластер узлы и восстановите состояние потерянных партиций. Чтобы восстановить состояние, используйте скрипт control.sh или укажите список кешей в методе Ignite.resetLostPartitions(cacheNames).

Пример, как восстановить состояние потерянных партиций с помощью вызова метода Ignite.resetLostPartitions(cacheNames):

Java#
ignite.resetLostPartitions(Arrays.asList("myCache"));

Пример, как восстановить состояние потерянных партиций с помощью control.sh:

control.sh --cache reset_lost_partitions myCache

Если не выполнить восстановление, операции чтения и записи (в зависимости от политики, которая настроена для кеша) из потерянных партиций сгенерируют исключение CacheException. Чтобы проверить, связано ли исключение с состоянием партиций, проанализируйте его корневую причину.

Java#
IgniteCache<Integer, Integer> cache = ignite.cache("myCache");

try {
    Integer value = cache.get(3);
    System.out.println(value);
} catch (CacheException e) {
    if (e.getCause() instanceof CacheInvalidStateException) {
        System.out.println(e.getCause().getMessage());
    } else {
        e.printStackTrace();
    }
}

Получить список потерянных партиций для кеша можно с помощью IgniteCache.lostPartitions().

Java#
IgniteCache<Integer, String> cache = ignite.cache("myCache");

cache.lostPartitions();

Восстановление после потери партиций#

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

Полностью in-memory-кластеры с политикой потери партиций IGNORE#

В этой конфигурации политика IGNORE применяется, только если включена базовая автонастройка с тайм-аутом 0 (настройка по умолчанию для in-memory-кластеров). Для таких конфигураций потеря партиций игнорируется, кеш продолжает работать, а потерянные партиции считаются пустыми.

Если базовая автонастройка отключена или установлен тайм-аут больше 0, политика IGNORE заменяется на READ_WRITE_SAFE.

Полностью in-memory-кластеры с политикой потери партиций READ_WRITE_SAFE или READ_ONLY_SAFE#

Действия пользователя блокируются, пока потерянные разделы не восстановятся с помощью метода Ignite.resetLostPartitions(cacheNames). После этого можно продолжить использовать кеш, но его данные будут потеряны.

Если базовая автонастройка отключена или установлен тайм-аут больше 0, верните узлы (хотя бы по одному владельцу для каждой партиции) в базовую топологию перед восстановлением потерянных партиций. В противном случае Ignite.resetLostPartitions(cacheNames) сгенерирует исключение ClusterTopologyCheckedException с сообщением:

Cannot reset lost partitions because no baseline nodes are online [cache=someCahe, partition=someLostPart].

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

Персистентные кластеры#

В кластерах, где все регионы данных персистентные, существует два способа восстановления после потери партиции (при условии, что данные не повреждены физически).

Первый способ восстановления:

  1. Верните все узлы в базовую топологию.

  2. Восстановите потерянные разделы — вызовите метод Ignite.resetLostPartitions(…​) для всех кешей.

Второй способ восстановления:

  1. Остановите все узлы.

  2. Запустите все узлы, включая вышедшие из строя, и активируйте кластер.

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

Кластеры с in-memory- и персистентными регионами данных#

В кластерах, где есть in-memory- и персистентные регионы данных, in-memory-кеши обрабатываются так же, как и в полностью in-memory-кластерах с политикой потери партиций READ_WRITE_SAFE. Persistent-кеши обрабатываются так же, как и в полностью персистентных кластерах.