Политика потери партиций (Partition Loss Policy)#
На протяжении жизненного цикла кластера возможны ситуации с недоступностью некоторых партиций из-за сбоев их основных (primary) и резервных (backup) узлов. Такие ситуации могут привести к частичной потере данных — их нужно решать в зависимости от вариантов использования.
Потеря партиции происходит, если ее основная и все резервные копии становятся недоступны кластеру, то есть когда недоступны основной и резервные узлы партиции. Если стали недоступными больше узлов, чем общее количество резервных партиций, произойдет потеря данных. Установить количество резервных партиций для кеша можно в его конфигурации — подробнее написано в разделе «Настройка резервных партиций».
При изменении топологии кластера DataGrid проверяет, не привело ли изменение к потере партиций. После этого в зависимости от настроенной политики потери партиций и базовых параметров автонастройки DataGrid разрешает или запрещает операции с кешами.
Для in-memory-кешей данные при потере партиций можно восстановить только через их повторную загрузку в кластер. В persistent-кешах физической потери данных не происходит, так как они хранятся на диске. После перезапуска кластера узлы, которые отключились или вышли из строя, возвращаются в кластер, и данные для них загружаются с диска. Чтобы продолжить использовать данные, восстановите состояние потерянных партиций — подробнее об этом написано ниже в разделе «Обработка потери партиций».
Настройка политики потери партиций#
Описание политик потери партиций:
Политика |
Описание |
|---|---|
|
Потеря партиций игнорируется. Кластер обрабатывает потерянные партиции как пустые. При запросе данных из таких партиций кластер возвращает пустые значения, как будто там никогда не было данных. |
|
Использование операций чтения и записи в потерянной партиции кеша приведет к генерации исключений. Можно выполнять чтение и запись в доступных партициях |
|
Кеш доступен в режиме только для чтения (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.
Пример, как включить событие в конфигурации кластера (подробнее об этом написано в подразделе «Включение и прослушивание событий» раздела «Работа с событиями»):
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):
ignite.resetLostPartitions(Arrays.asList("myCache"));
Пример, как восстановить состояние потерянных партиций с помощью control.sh:
control.sh --cache reset_lost_partitions myCache
Если не выполнить восстановление, операции чтения и записи (в зависимости от политики, которая настроена для кеша) из потерянных партиций сгенерируют исключение CacheException. Чтобы проверить, связано ли исключение с состоянием партиций, проанализируйте его корневую причину.
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().
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].
Это означает, что безопасное восстановление невозможно. Если по какой-либо причине узлы нельзя вернуть, например из-за сбоя оборудования, исключите их из базовой топологии вручную перед попыткой восстановления потерянных партиций.
Персистентные кластеры#
В кластерах, где все регионы данных персистентные, существует два способа восстановления после потери партиции (при условии, что данные не повреждены физически).
Первый способ восстановления:
Верните все узлы в базовую топологию.
Восстановите потерянные разделы — вызовите метод
Ignite.resetLostPartitions(…)для всех кешей.
Второй способ восстановления:
Остановите все узлы.
Запустите все узлы, включая вышедшие из строя, и активируйте кластер.
Если некоторые узлы невозможно вернуть, исключите их из базовой топологии перед попыткой восстановить состояние потерянных партиций.
Кластеры с in-memory- и персистентными регионами данных#
В кластерах, где есть in-memory- и персистентные регионы данных, in-memory-кеши обрабатываются так же, как и в полностью in-memory-кластерах с политикой потери партиций READ_WRITE_SAFE. Persistent-кеши обрабатываются так же, как и в полностью персистентных кластерах.