АрхитектураРаспределённые системыИнженер по распределённым системам

В Raft лидер получил подтверждения большинства узлов для записи из предыдущего терма. Может ли он немедленн...

В Raft лидер получил подтверждения большинства узлов для записи из предыдущего терма. Может ли он немедленно считать эту запись зафиксированной?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

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

Исторический контекст

В реплицируемом журнале важно отличать факт копирования записи на несколько узлов от её окончательной фиксации. Запись может находиться на большинстве реплик, но затем быть перезаписана новым лидером, если она относится к более старому терму и ещё не была закреплена правилом консенсуса.

Raft использует отдельное правило фиксации записей предыдущих термов, чтобы сохранить свойство leader completeness: новый лидер обязан содержать все записи, которые уже были зафиксированы в предыдущих термах.

Постановка проблемы

Предположим, запись терма 7 скопирована на три из пяти узлов. Лидер терма 7 выходит из строя до того, как зафиксировал её. В терме 8 может быть избран кандидат с более свежим журналом, но без этой записи: узлы с записью могут проголосовать за него, если его журнал выглядит более актуальным.

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

Подробное решение

Лидер может зафиксировать запись напрямую, когда выполняются два условия: запись находится в журнале текущего терма лидера и её индекс подтверждён большинством узлов. После этого лидер распространяет информацию о зафиксированном индексе, а узлы применяют записи к состоянию только до этого индекса.

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

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

Практическое следствие: после избрания лидеру часто добавляют no-op-запись текущего терма. Это позволяет безопасно зафиксировать ранее унаследованные записи и быстрее установить актуальный commit index. До этого клиентские операции могут быть записаны на большинстве узлов, но их подтверждение как окончательно принятых небезопасно.

Ситуация из практики

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

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

На практике выбирают третий вариант. Он допускает короткую задержку после смены лидера, но предотвращает подтверждение результата, который новый лидер впоследствии может отменить.

Что кандидаты часто упускают

  1. Вопрос: Может ли запись текущего терма быть зафиксирована, если лидер получил подтверждение от большинства, но сам ещё не применил её к состоянию?

Ответ: Да. Фиксация записи в журнале и применение к локальному состоянию — разные этапы. После подтверждения большинством запись может получить статус committed, даже если лидер ещё не выполнил соответствующее изменение состояния. Применение должно произойти позже, в порядке журнала, чтобы состояния узлов оставались согласованными.

  1. Вопрос: Почему после фиксации записи текущего терма становятся зафиксированными более ранние записи, включая записи старых термов?

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

  1. Вопрос: Что произойдёт, если лидер сообщит клиенту об успехе сразу после локальной записи операции, не дожидаясь фиксации большинством?

Ответ: При отказе лидера операция может исчезнуть или быть заменена новым лидером. Клиент уже считает её успешной, но кластер не обязан сохранить такой результат. Чтобы обещать устойчивый успех, лидер должен дождаться требуемого уровня фиксации, а затем корректно сообщить клиенту о результате; ожидание только локальной записи обеспечивает лишь временное принятие операции.