Raft и отказоустойчивость¶
Raft — алгоритм для решения задач консенсуса в сети ненадежных вычислений. В Picodata этот алгоритм применяется для репликации глобальных таблиц и всей конфигурации кластера (топологии, схемы данных и другой информации). Raft обеспечивает согласованность данных на всех инстансах кластера.
Raft предполагает, что в кластере всегда существует явно выделенный
лидер (leader
). Только он отправляет новые записи на другие узлы
кластера. Если обычный узел (follower
) долго не получает сообщений от
лидера, то он переходит в состояние "кандидат" (candidate
) и проводит
процедуру голосования.
Динамическое переключение голосующих узлов в Raft (Raft voter failover)¶
Все узлы Raft в кластере делятся на два типа: голосующие (voter
) и
неголосующие (learner
). За консистентность raft-группы отвечают только
первые. Для применения каждой записи требуется собрать кворум из N/2 +
1
голосующих узлов. Неголосующие узлы в кворуме не участвуют и всегда
находятся в состоянии follower
.
Чтобы сохранить баланс между надежностью кластера и удобством его
эксплуатации, в Picodata предусмотрено автоматическое распределение
голосующих узлов. Количество голосующих узлов в кластере не настраивается
и зависит только от количества инстансов из тиров со свойством
can_vote
, которое является полем системной таблицы _pico_tier
.
Зависимость количества голосующих узлов в Raft от количества инстансов
из тиров со свойством can_vote
:
- 1 инстанс — 1 голосующий узел;
- 2 инстанса — 2 голосующих узла;
- 3 или 4 инстанса — 3 голосующих узла;
- 5 и более инстансов — 5 голосующих узлов;
Если один из голосующих узлов становится недоступным
или прекращает работу (что может нарушить кворум в Raft), то тип voter
автоматически присваивается одному из доступных и подходящих
для голосования узлов.
Переключение происходит незаметно для пользователя.
Пример распределения голосующих узлов¶
Приведем пример кластера с одним уровнем распределения узлов между
локациями. Пусть это будет два датацентра (MSK
, SPB
) и третья
локация для арбитража (решающего голоса в случае потери сетевой
связности между датацентрами). Вне зависимости от общего числа узлов в
кластере предполагается наличие всего 5 голосующих узлов, которые, в
данном случае, распределятся так:
- 2 в локации
MSK
; - 2 в локации
SPB
; - 1 в третьей локации.
Если весь датацентр в локации SPB
теряет доступность и связь с арбитром,
то его 2 голосующих узла перемещаются в датацентр локации MSK
. При
восстановлении связности, голосующие узлы возвращаются обратно и
исходная конфигурация восстанавливается.
В случае, если лишь отдельный сервер с голосующим узлом в SPB
теряет
связь, то право голоса перемещается внутри локации, т.е. переходит к
другому узлу в SPB
. Если сервер восстанавливает связь, то он уже не
станет автоматически голосующим, так как схема распределения не будет этого
требовать.
См. также:
Использование тиров для повышения отказоустойчивости¶
Применение в кластере тиров позволяет более выгодно использовать
вычислительные ресурсы с точки зрения управляемости кластера. На
отказоустойчивость raft-лидера существенно влияет общая вычислительная
нагрузка на его узел, так как от нее, в том числе, зависит соблюдение
таймаутов на запись данных о состоянии кластера в глобальные таблицы.
Поэтому, для повышения надежности промышленного кластера имеет смысл
выделить все голосующие узлы в отдельный тир со свойством can_vote =
true
и освободить их от хранения и обработки данных шардированных
таблиц. Инстансы такого тира следует объединить в один репликасет и с
помощью доменов отказа распределить их по разным датацентрам (либо
другим сущностям, определяющим отказоустойчивость). Соответственно,
число таких инстансов определяет фактор репликации в таком тире-арбитре
(от 3 до 5, так как в кластере не может быть более 5 голосующих узлов).
Инстансы, участвующие в хранении и обработке шардированных данных,
следует объединить в один или несколько других тиров со свойством
can_vote = false
.
Подобное разделение поможет исключить ситуации, когда raft-лидер не справляется с управлением кластера из-за возросшей нагрузки по обработке данных.