Какую проблему решает RaftЧтобы данные не пропали вместе с сервером, их хранят сразу на нескольких серверах. Такие серверы называют репликами.
Один из них главный (лидер): клиент пишет в него, а лидер пересылает запись остальным.
Raft – правила, по которым реплики договариваются, кто сейчас лидер и какая запись точно сохранена на всех репликах, чтобы падение сервера не стёрло то, что клиенту уже подтвердили.
🧩 Серверы не знают, упал ли лидер
Реплики видят одно: от лидера перестали приходить сообщения. Упал он, отрезан сетью или просто тормозит – по этой тишине не отличить.
Поэтому, назначая нового лидера, серверы действуют в ситуации неопределённости: старый может быть жив и продолжать принимать записи.
💥 Проблемы, которые решает Raft
Возьмём серверы A, B и C, лидер – A. Вот что бывает, если лидера назначает внешний координатор, а A отвечает клиенту "OK", не дожидаясь, пока запись дойдёт до B и C.
🔹 1. Два лидера сразу. Сеть отрезала A от B и C. A жив: клиент 1 пишет на него x = 1 и получает "OK". Координатор не слышит A и назначает B, клиент 2 пишет туда x = 2 и тоже получает "OK".
🔹 2. Подтверждённая запись пропадает. Сеть восстановилась, лидер должен остаться один, и A понижают, стирая его x = 1, хотя клиенту 1 уже сказали "OK". Бывает и без разрыва: A подтвердил запись, не дождавшись B и C, и упал, а новый лидер B о ней не знает.
🔹 3. Копии расходятся. Если записи A не стирать, у A и B окажутся конфликтующие записи. Сводят их вручную или по правилу "побеждает последняя", но тогда одна из них теряется, хотя клиенту ответили "ОК".
🔹 4. Без автоматики запись стоит. Чтобы не получить двух лидеров, переключение оставляют человеку. Тогда после падения A запись стоит, пока дежурный не разберётся, кто жив, и не назначит лидера руками.
🎯 Raft сделал консенсус понятным
Каждое из четырёх правил Raft закрывает проблемы выше:
🔹 OK от лидера клиенту – только когда запись сохранило большинство. Отрезанный A один и подтвердить x = 1 не может;
🔹 у каждых выборов лидера свой номер – срок (term). В сроке у сервера один голос, а лидеру нужно большинство, поэтому двух лидеров в сроке не бывает. Когда A возвращается после падения, он видит, что срок уже не его, становится репликой и актуализирует свой лог по B, стирая только записи без "OK";
🔹 серверы голосуют только за кандидата с журналом не старее своего. Подтверждённая запись есть хотя бы у одного из голосующих, и он не отдаст голос кандидату без неё. Значит, новый лидер уже содержит всё подтверждённое;
🔹 выборы запускаются сами: сервер, который долго не слышал лидера, выдвигается по своему случайному таймеру. Если он принял тормозящего лидера за упавшего, будут лишние выборы, а не потеря данных.
Raft был создан специально, чтобы алгоритм был простым. Подобные алгоритмы были и до него, но они были невероятно сложными и всех свои.
Например, Paxos, но он в основном описывает, как договориться об одном значении, а журнал записей и выборы лидера каждая команда достраивала сама.
По гарантиям он в одном классе с Multi-Paxos и Zab (внутри ZooKeeper): если они у вас уже работают, менять их незачем.
⚖️ Выбор решает модель отказов
🔹 Raft – его берут, когда серверы свои и не подменят данные, а защита нужна от падения сервера и обрыва связи, чтобы порядок записей везде совпадал. Кластер из 2f+1 серверов переживает f отказов.
На нём стоят etcd, Kubernetes, Consul, метаданные Kafka (KRaft), CockroachDB, TiKV/TiDB и quorum queues в RabbitMQ.
🛡 BFT (византийская отказоустойчивость) нужна, если сервер способен лгать: Raft защищает от падений и обрывов связи, но не от ложных данных. PBFT, HotStuff и CometBFT платят за это числом серверов – 3f+1, то есть 4 вместо 3 на один сбой.
🌊 Когда доступность записи важнее согласованности, подходят кворумы без консенсуса, как в Cassandra и Riak. При R+W>N кворумы пересекаются, но одного порядка записей нет. Цена – расхождение копий.
Raft защищает только то, что прошло через его журнал. Если консенсус у вас лишь выбирает главного, а данные копируются асинхронно, копии могут разойтись, когда после разрыва переключат главного