EnglishРусский Map
Distributed Consensus

Византийский отказ

title
Византийский отказ
type
concept
summary
Режим отказа, при котором узел выдаёт неверный результат, выглядя при этом исправным
tags
distributed-systems, fundamentals
created
2026-04-07
updated
2026-07-22
lang
ru
translation_of
byzantine-fault
source_updated
2026-07-22
translated
2026-09-01
translator
lllm/antigravity/gemini-3.7-flash-high

Режим отказа, когда компонент не просто перестаёт работать, а продолжает функционировать, но выдаёт некорректный или вводящий в заблуждение результат. Назван по задаче византийских генералов (Lamport, Shostak, Pease, 1982) - мысленному эксперименту о координации армии, когда среди генералов могут быть предатели.

Задача о генералах

Несколько генералов окружили город и должны договориться, атаковать или отступать. Связь они держат через гонцов. Часть генералов могут оказаться предателями и рассылать противоречивые приказы - сообщать одному соседу "атака", а другому "отступление", чтобы сорвать координацию: часть армии пойдёт в атаку, пока остальные отступают.

Строго доказанный результат: чтобы выдержать f предателей, всего требуется более 3f+1 генералов. Если генералов 3 и один из них предатель, 2 верных генерала не смогут надёжно определить, каким сообщениям верить. При 4 генералах и 1 предателе голосование большинством позволяет нейтрализовать недобросовестного участника.

Crash-отказы и византийские отказы

Crash-отказ устроен просто: процесс останавливается. Он больше не отправляет сообщений. Другие процессы (со временем) могут обнаружить это по отсутствию связи. Это более простая модель отказов - с ней справляются такие алгоритмы, как Paxos и Raft.

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

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

Crash-отказ и византийский отказ - две крайности, которые обычно называют разработчики ПО. Но всё пространство моделей отказов (постоянные против перемежающихся, схемы резервирования для их маскировки и метрики надёжности для их сравнения) с аппаратной стороны разобрано в книге Дубровой fault-tolerant-design.

Примеры из реального мира

  • Диск, который молча возвращает повреждённые данные вместо сообщения об ошибке
  • Неправильно настроенный сервер, который сообщает клиентам об успехе, но на самом деле не сохраняет записи
  • Скомпрометированный узел в peer-to-peer сети, который врёт о том, какие блоки у него есть
  • LLM-агент, который уверенно выдаёт код на основе неверно понятого промпта: он не упал, а просто интерпретировал задачу иначе, чем все остальные агенты (log-distributed-llms)

Борьба с византийскими отказами

PBFT (Practical Byzantine Fault Tolerance) - классический алгоритм: каждый узел рассылает своё решение всем остальным узлам, и узлы принимают решение большинства. Дорого: O(n^2) сообщений на каждое решение.

Преобразование в crash-отказы - более дешёвая альтернатива. Вместо византийски-устойчивых протоколов добавляются внешние валидаторы, проверяющие корректность вывода. Агент, выдавший код, который не проходит тесты, теперь превращается в зафиксированный сбой (нужно повторить попытку), а не в незаметное расхождение. Именно эту стратегию log-distributed-llms рекомендует для мультиагентных LLM-систем, и по этой же причине базы данных используют контрольные суммы при чтении с диска.

Проверка с участием человека (human-in-the-loop) выполняет аналогичную функцию: человек, проверяющий вывод агента, работает детектором византийских отказов, отлавливая случаи, когда результат работы агента выглядит правдоподобным, но неверен.