Прямой ответ
Raft — алгоритм консенсуса, который позволяет группе узлов договориться о последовательности записей даже при отказах части узлов. Он спроектирован как понятная альтернатива Paxos: та же задача, но декомпозированная на три подзадачи — выборы лидера, репликация лога и безопасность. Классическая конфигурация — нечётное число узлов (3, 5, 7): кворум составляет большинство, поэтому при отказе меньшинства кластер продолжает принимать записи, а при разделении сети меньшая сторона просто перестаёт обслуживать запись — это базовая защита от split brain.
Ключевые понятия:
- Роли. Каждый узел находится в одном из трёх состояний:
leader,follower,candidate. В любой момент терма не более одного лидера; все записи идут через него, а followers лишь отвечают на запросы. - Терм (term). Логический «эпохальный» счётчик. Каждые выборы увеличивают терм. Если узел получает сообщение с более высоким термом, он немедленно переходит в follower — так кластер избавляется от устаревших лидеров.
- Выборы лидера. Если follower не получил heartbeat от лидера за
election timeout(в эталонной реализации — случайное значение в диапазоне 150–300 мс), он становится кандидатом, увеличивает терм и рассылаетRequestVote. Побеждает кандидат, набравший большинство голосов; узел голосует не более одного раза за терм. - Репликация лога. Лидер принимает команды клиентов, добавляет их в свой лог и рассылает
AppendEntries. Когда запись скопирована на большинство узлов, она считается зафиксированной (committed) и применяется к состоянию. - Ограничение выбора лидера. Кандидат получает голос только если его лог не менее актуален, чем лог голосующего (сравнение по индексу и терму последней записи). Это гарантирует, что зафиксированные записи не потеряются после смены лидера.
Практический смысл: Raft даёт линеаризуемую запись и строгий порядок операций ценой доступности при потере большинства. Именно поэтому его используют там, где важна метаданная согласованность, а не объём данных.
Практика: где Raft работает в вашем стеке
etcd. Хранилище конфигурации Kubernetes использует Raft для согласованности ключ-значение; etcd прямо рекомендует нечётное число участников и предупреждает, что потеря кворума делает кластер недоступным для записи.
Patroni. Надстройка для PostgreSQL использует распределённое хранилище (etcd/Consul/ZooKeeper) как DCS: лидер держит ключ с TTL, а при его исчезновении узлы устраивают гонку за лидерство — подробнее в статье про автоматический failover PostgreSQL.
Consul, TiKV, CockroachDB, Kafka (KRaft). В Kafka контроллеры с версии 3.x работают в режиме KRaft, где метаданные кластера хранятся в Raft-логе вместо ZooKeeper — это упрощает эксплуатацию и ускоряет восстановление.
Что настраивать на практике:
- Число узлов. Три узла выдерживают отказ одного, пять — двух. Чётное число не добавляет отказоустойчивости, но увеличивает задержку кворума.
- Разнесение по зонам. Узлы должны жить в разных стойках/зонах; иначе отказ одной зоны уносит кворум целиком.
- Тайминги.
election timeoutдолжен заметно превышать RTT и время fsync на диске. На медленных дисках слишком агрессивный таймаут приводит к «выборам вхолостую» и просадкам записи. - Снимки (snapshots). Лог Raft бесконечно растёт, поэтому узлы периодически сохраняют снапшот состояния и обрезают лог. Следите за размером снапшота: слишком большой — долгая отправка новому узлу, слишком частая генерация — лишняя нагрузка на диск.
Практический сценарий: кластер из трёх узлов теряет лидера
Контекст: etcd из трёх узлов в трёх зонах обслуживает конфигурацию сервиса; один узел упал вместе с зоной.
- Детекция. Followers не получают heartbeat. Через
election timeoutоба становятся кандидатами; случайный разброс таймаута почти всегда предотвращает одновременную победу. - Выборы. Один кандидат собирает 2 голоса из 3 (большинство), становится лидером нового терма и возобновляет запись. Второй кандидат видит более высокий терм и возвращается в follower.
- Проверка лога. Новый лидер сравнивает логи и дописывает недостающие записи на follower — зафиксированные записи при этом не теряются.
- Наблюдаемость. На дашборде видно всплеск
etcd_server_leader_changes_seen_totalи кратковременный рост задержки записи; алерт на частые смены лидера — признак проблем с диском или сетью, а не «нормальной жизни» кластера. Как строить такие алерты — в статье про правила оповещения Alertmanager. - Восстановление. Узел возвращается, получает снапшот и недостающий лог, догоняет кластер.
Результат: недоступность записи длилась секунды, данные не потеряны. Вывод: Raft корректно обработал отказ, потому что кворум (2 из 3) сохранился; если бы упали две зоны, кластер стал бы только читаемым/недоступным — и это ожидаемое поведение, а не баг.
FAQ
Чем Raft отличается от Paxos? Оба решают задачу консенсуса, но Raft жёстко структурирован: сильный лидер, явные термы, правило актуальности лога. Paxos (особенно Multi-Paxos) допускает больше свободы в реализации, из-за чего корректные реализации сложнее писать и проверять. На практике Raft выбирают, когда важна понятность и предсказуемость поведения, — сравнение подходов — в статье про Paxos.
Сколько узлов нужно и что будет при потере одного? Минимум три. Кворум для трёх — два, поэтому отказ одного узла не прерывает запись. Для пяти узлов кворум — три, то есть допустимы два отказа. Чётное число (например, четыре) даёт кворум три — ту же отказоустойчивость, что и три узла, но с лишней нагрузкой.
Можно ли читать данные с follower без потери согласованности?
Наивное чтение с follower может вернуть устаревшее значение. Для строгой согласованности чтение должно проходить через лидера либо использовать механизм ReadIndex/lease read, при котором лидер подтверждает своё лидерство кворумом перед ответом. Слабые чтения с реплик — осознанный компромисс, описанный в материале про модели согласованности.
Как Raft защищает от split brain? Любое решение требует большинства голосов. При разделении сети две половины не могут одновременно набрать большинство, поэтому лидером остаётся только узел в «мажоритарной» части. Меньшая сторона отклоняет запись до восстановления связности — детали и смежные сценарии разобраны в статье про split brain.
Источники: raft.github.io (спецификация Raft), etcd.io/docs (рекомендации по кластеру), Patroni docs — ссылки в шапке.