Top.Mail.Ru
Автоматические выборы лидера | Tarantool
Репликация / Автоматические выборы лидера
Tarantool
Узнайте содержание релиза 2.8
Репликация / Автоматические выборы лидера

Автоматические выборы лидера

Автоматические выборы лидера

В Tarantool, начиная с версии 2.6.1, есть встроенная функциональность для управления автоматическими выборами лидера (automated leader election) в наборе реплик (replica set). Эта функциональность повышает отказоустойчивость систем на базе Tarantool и снижает зависимость от внешних инструментов для управления набором реплик.

Ниже описаны следующие темы:

В Tarantool используется модификация Raft — алгоритма синхронной репликации и автоматических выборов лидера. Полное описание алгоритма Raft можно прочитать в соответствующем документе.

Синхронная репликация и выборы лидера в Tarantool реализованы как две независимые подсистемы. Это означает, что можно настроить синхронную репликацию, а для выборов лидера использовать альтернативный алгоритм. Встроенный механизм выборов лидера, в свою очередь, не требует использования синхронных спейсов. Синхронной репликации посвящен этот раздел документации. Процесс выборов лидера описан ниже.

Автоматические выборы лидера в Tarantool гарантируют, что в каждый момент времени в наборе реплик будет максимум один лидер — узел, доступный для записи. Все остальные узлы будут принимать исключительно запросы на чтение.

Когда функция выборов включена, жизненный цикл набора реплик разделен на так называемые термы (term). Каждый терм описывается монотонно растущим числом. После первой загрузки узла значение его терма равно 1. Когда узел обнаруживает, что не является лидером и при этом лидера в наборе реплик уже какое-то время нет, он увеличивает значение своего терма и начинает новый тур выборов.

Выборы лидера происходят посредством голосования. Узел, начинающий выборы, голосует сам за себя и отправляет другим запросы на голос. Каждый экземпляр голосует за первый узел, от которого пришел такой запрос, и далее в течение всего терма ожидает избрания лидера, не выполняя никаких действий.

Узел, собравший кворум голосов, становится лидером и оповещает об этом другие узлы. Голоса могут разделиться, если ни один узел не получит кворума. В этом случае спустя случайное время происходят перевыборы: каждый узел увеличивает значение терма и начинает новый тур, если за период ожидания не получил запроса на голос от узла, чей терм больше. В итоге определяется лидер кластера.

Узлы, не являющиеся лидерами, называются последователями (followers). Узлы, которые начинают новый тур выборов, называются кандидатами (candidates). Избранный лидер отправляет остальным узлам контрольные сигналы (heartbeats), оповещая о том, что он работает (alive). Если контрольные сигналы не приходят в течение времени, заданного параметром replication_timeout, начинаются новые выборы. Чтобы алгоритм Raft гарантированно выполнялся, термы и голоса сохраняются на каждом экземпляре.

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

Необходимо, чтобы все узлы, включенные в процесс выборов, были соединены попарно и образовывали полную ячеистую топологию (full mesh). Для передачи запросов, связанных с голосованием, и других внутренних сообщений требуется прямая связь между узлами.

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

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

box.cfg({
    election_mode = <string>,
    election_timeout = <seconds>,
    replication_timeout = <seconds>,
    replication_synchro_quorum = <count>,
})
  • election_mode — определяет роль узла в процессе выборов лидера. Подробное описание параметра приводится в справочнике по настройке.
  • election_timeout — задает промежуток времени между турами в случае разделения голосов и последующих перевыборов. Подробное описание параметра приводится в справочнике по настройке.
  • replication_timeout — параметр репликации replication_timeout, используемый для выборов лидера. Активный лидер отправляет сообщения контрольного сигнала каждые <replication_timeout> секунд. Значение параметра по умолчанию — 1. Если лидер не отправляет сообщений контрольного сигнала в течение <replication_timeout> * 4 секунд, он считается недоступным (dead) и начинаются новые выборы.
  • replication_synchro_quorum — параметр репликации replication_synchro_quorum, используемый для настройки кворума. Значение по умолчанию — 1, то есть каждый узел, проголосовав за себя, немедленно становится лидером. Лучше всего задать этому параметру значение (<размер кластера> / 2) + 1. В противном случае нет гарантий, что в каждый момент времени в кластере будет только один лидер.

Важно также понимать, что статус лидера — не единственное, что требуется узлу, чтобы быть доступным для записи. Параметр read_only на узле-лидере должен иметь значение false (box.cfg{read_only = false}). Необходимо также, чтобы выполнялось условие, заданное параметром replication_connect_quorum (box.cfg{replication_connect_quorum = <count>}), или же этот параметр должен быть отключен (box.cfg{replication_connect_quorum = 0}).

Ничто не мешает задать для параметра read_only значение true, но это сделает лидера недоступным для записи. На сам процесс выборов параметр никак не влияет, поэтому голосовать и быть лидером может даже экземпляр, доступный только для чтения.

Чтобы отслеживать текущий статус узла в выборах лидера, можно использовать функцию box.info.election. Подробные сведения читайте в описании функции.

Пример:

tarantool> box.info.election
---
- state: follower
  vote: 0
  leader: 0
  term: 1
...

Журнальные записи о выборах на основе алгоритма Raft отмечаются префиксом RAFT:. В журнал вносятся такие события, как обработка новых сообщений Raft, изменение статуса узла, голосование, увеличение значения терма и пр.

Механизм выборов лидера не будет корректно работать, если кворум меньше <размер кластера> / 2 или равен этому значению, поскольку в этом случае два лидера могут быть избраны одновременно.

Допустим, есть пять узлов. Если значение кворума — 2, то node1 и node2 оба могут проголосовать за node1. При этом node3 и node4 оба могут проголосовать за node5. Тогда выборы выиграют и node1, и node5. Но если в качестве значения кворума установлено большинство, то есть (<размер кластера> / 2) + 1 или больше, то разделение голосов поровну невозможно.

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

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

Кроме того, синхронные транзакции, оставшиеся от прежнего лидера, не финализируются автоматически при выборах нового. Финализацию следует выполнять вручную с помощью функции box.ctl.promote. В будущих релизах финализация станет автоматической.