Проблема split-brain и слежение за кворумом
Проблематика
Рассматриваемый случай касается многосерверного кластера, но возможен уже в двухсерверной инсталляции. Некоторые сервисы управляют данными, хранят данные. Для этого используются распределенное объектное хранилище, либо подключение к мастер-экземпляру postgresql (при наличии потоковой репликации на рекавери-экземпляр). Необходимо сохранять целостность данных.
Если существует риск потери связи между серверами при сохранении изолированной работоспособности, то существует риск разделения точки целостности. Платформа разделена на микросервисы, и имеет несколько различных точек целостности.
Допустим, возникли два острова - часть абонентов подключены к первому острову, часть абонентов подключены ко второму. Платформа избавлена от центрального узла. Поэтому каждый остров в короткое время стремится собраться в полнофункциональную систему на доступных в острове серверах. Ограничением этому является только конфигурация конкретного экземпляра платформы. Итак, резервные экземпляры микросервисов, имеющих точку целостности, в короткий срок активируются.
В итоге в пределе может образоваться две системы, каждая со своей группой абонентов, и каждая готова к обслуживанию. Однако:
-
возможна дублированная инициация исходящих взаимодействий;
-
у каждого из островов недоступна часть абонентов;
-
транзакции модификации данных различны и нарушают целостность.
Негативные последствия очевидно проявляются более ярко в момент, когда связь между островами восстанавливается:
-
Слияние данных в общем случае невозможно, поэтому модификации одного из островов теряются в пользу данных другого.
-
Если БД postgresql установлена здесь же, то вместо активной потоковой репликации обнаруживается два мастер-экземпляра. Процесс восстановления потоковой репликации связан с полным бэкапом, и, в зависимости от размеров баз данных и скорости дисков под ними, это может занимать часы. Все это время реплика фактически отсутствует, и система не готова к потере сервера с мастер-экземпляром БД.
Эта проблема носит условное название Split-brain.
Обзор решения
Решению этой проблемы служит концепция кворума.
Если остров содержит меньше, чем 50% + 1 сервер, то его сервисы, способные нарушить целостность, следует принудительно тушить:
-
фасадные сервисы, через которые абоненты подключаются и регистрируются;
-
сервисы-инициаторы, которые способны генерировать новые записи;
-
особенно контроллер репликаций postgresql, чтобы он не превратил рекавери в мастер, и не привел к дальнейшей многочасовой операции восстановления потоковой репликации;
-
любые сервисы с точкой целостности.
На какие бы острова система не распалась, не существует двух островов размером 50% + 1 сервер.
Особняком стоит случай, когда система может распасться на две равные половины. Это случай
-
двухсерверных инсталляций с разнесенными серверами и непрямым подключением, либо с возможным стихийным обслуживанием серверов выражающимся в отключении одного из серверов от коммутатора.
-
инсталляций с четным количеством серверов, распределенных на два датацентра.
И в том и в другом случае преследуется цель обеспечить сервер на одной половине при выходе второй половины из строя. Но побочным эффектом является возможный split-brain.
Очевидно, кворум в его обычном понимании не позволит ни одной из половин находиться в активном состоянии.
Решением может служить добавление к кластеру еще одного узла. Это может быть:
-
еще один сервер, пусть даже не нагруженный конфигурацией;
-
произвольный арбитр во внешней сети, пинг которого означает сохранение публичной сети.
Случай арбитра заслуживает большего внимания, поскольку более прост, менее требователен к ресурсам, и в то же время создает еще одно ответвление. Тот остров, который оказывается не связан с арбитром, лишается возможности оказаться в кворуме. Тот остров, который связан с арбитром, получает шанс оказаться активным.
Рассмотрим случай, когда между островами пропала внутренняя сеть, но при этом оба острова через внешнюю сеть пингуют арбитра. В этом случае проблема split-brain остается реальной, но через внешнюю сеть острова оказываются доступны друг другу - через сеть того самого арбитра. Чтобы в этом случае остров получил разрешение на активацию, он пытается обратиться к недоступным по внутренней сети серверам другого острова, и провести выборы. Разрешение дается в случае если другой остров признал себя фолловером, либо другой остров недоступен.
Выборы осуществляются на основании специальных порядковых значений, заданных в конфигурации для серверов, а при их отсутствии, на основании лексикографической сортировки имен серверов конфигурации. Тот кто имеет в своем составе минимальное значение, признается лидером. Для того, чтобы связаться через внешнюю сеть, для всех серверов в конфигурации может быть задан специальный URL для этой цели. Серверы обращаются по этим URL к веб-серверам (микросервисам), расположенным на этих серверах.
Очевидно, что выпадение любого сервера из более чем двухсерверной конфигурации также способно спровоцировать split-brain. Поэтому стоит и для этих случаев настроить слежение за кворумом.
Настройка слежения за кворумом
Кворум настраивается в конфигурации.
-
Параметр раздела general или sites: 'check_quorum' - активация слежения за кворумом.
-
Параметр раздела general или sites: 'odd_referee' - указание внешнего арбитра для четно-серверных конфигураций.
-
Параметр сервера: 'wan_url' - адрес.
-
Параметр сервера: 'quorum_leadership_key'.
-
Дополнительно на каждом сервере следует добавить веб-сервер - не важно с обособленным ограниченным назначением, либо общей доступности.
По умолчанию в автоматически формируемых конфигурациях слежение за кворумом отключено.
Механизм работы
Слежение за кворумом осуществляется в серверных нодах. Остальные ноды по необходимости опрашивают и подписываются на информацию о наличии кворума в острове с участием текущего сервера.
За кворумом следят:
Поскольку доменный центр в распределенной системе резервируется в режиме active-passive и следит за кворумом, то в зависимости от него оказываются и другие микросервисы, работающие с доменным деревом, но резервируемые в режиме active-active, в частности:
-
супервизоры продуктового слоя (msvc),
-
и как следствие все продуктовые микросервисы.
Поскольку все микросервисы работающие с распределенным объектным хранилищем резервируются в режиме active-active, целостность этих хранилищ не нарушается.
Поскольку mware в распределенной системе резервируется в режиме active-passive и следит за кворумом, то в зависимости от кворума оказываются:
-
контроллер потоковой репликации postgresql (превращает рекавери-экземпляра БД в мастера и восстанавливает потоковую репликацию),
-
контроллер создания резервных копий,
-
контроллер обеспечения горячего резервирования домена,
-
контроллер запуска служебных сценариев по расписанию,
-
и др.
Таким образом, спустя пару секунд после потери кворума на острове не происходит никаких операций, никто не подключается, не регистрируется, никаких обращений к внешним системам и провайдерам не происходит.