Сейчас идёт тестирование: код на GitHub будет открыт после завершения.

Процедура непрерывного перезапуска (rolling)

Есть только один ключевой принцип: большинство должно оставаться в строю всегда. При 3 узлах можно выводить не более 1 одновременно, при 5 — не более 2.

  1. Сначала перезапускайте followers (нелидирующие узлы) по одному — лидер при этом продолжает обслуживание. Прежде чем переходить к следующему узлу, убедитесь, что перезапущенный узел догнал состояние через репликацию лога/снапшот от пиров.
  2. В последнюю очередь выводите лидера. Оставшиеся узлы обнаруживают прекращение heartbeat и избирают нового лидера за 0,5–1 секунду. В этот промежуток клиентские запросы получают E no_leader, но официальный клиент прозрачно повторяет их, поэтому со стороны приложения это выглядит лишь как короткая задержка.
  3. Снова поднимите выведенного старого лидера — он присоединяется как follower и догоняет состояние (автоматически роль лидера не возвращается).

Состояние блокировок сохраняется, пока держится большинство — блокировки, выданные и освобождённые во время перезапуска, тоже проходят через commit и не теряются.

Поток (на примере 3 узлов)

Leader
Follower 1
Follower 2
① перезапуск follower 1 — лидер продолжает обслуживание
догон через репликацию лога / снапшот
② после подтверждения догона — перезапуск follower 2
догон через репликацию лога
③ в последнюю очередь — перезапуск лидера
Vote → новый лидер избран за 0,5–1 секунду
старый лидер присоединяется как follower и догоняет
RPC консенсуса (Raft)

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