Как достигается консенсус в распределенных системах
Что проверяют
Понимаете ли вы, какую задачу решает консенсус и чего он стоит, а не только знаете названия Paxos и Raft. Python-разработчик редко пишет такой алгоритм сам, поэтому важно знать, где он уже работает под вашим сервисом. Следом обычно спрашивают, сколько узлов нужно кластеру и что происходит при разделении сети.
Как отвечать
Консенсус это договорённость нескольких узлов об одном значении или одном порядке операций в журнале, даже если часть узлов упала или недоступна. Опора практических алгоритмов это кворум большинства: кластер из 2f + 1 узлов переживает отказ f узлов. Три узла выдерживают потерю одного, пять узлов потерю двух.
- Raft: роли лидера, фолловера и кандидата. Лидер выбирается голосованием с номером срока (term), таймауты выборов случайные, чтобы кандидаты не делили голоса бесконечно. Лидер реплицирует журнал, запись считается зафиксированной после подтверждения большинством, а выиграть выборы может только узел с достаточно свежим журналом;
- Paxos: две фазы, prepare/promise и accept/accepted, роли proposer, acceptor и learner. Для потока команд используют Multi-Paxos с устойчивым лидером;
- византийские отказы: если узлы могут лгать, нужны алгоритмы класса PBFT и
3f + 1узлов.
Упомяните теорему FLP: в полностью асинхронной сети детерминированный алгоритм не может гарантировать завершение даже при одном отказе, поэтому реальные системы полагаются на таймауты.
Где это встречается рядом с Python-сервисом: etcd и Consul работают на Raft, ZooKeeper на своём протоколе ZAB, Kafka с версии 4.0 использует только KRaft, Patroni держит лидера PostgreSQL через etcd, Consul или ZooKeeper, а выборы лидера среди подов делаются через объект Lease в Kubernetes.
Где спотыкаются
Считают, что четыре узла надёжнее трёх. Большинство из четырёх это три, поэтому кластер по-прежнему переживает только один отказ, а кворум собирать дороже.
Путают консенсус с двухфазным коммитом. 2PC блокируется при падении координатора и не решает задачу согласия при отказах.
Не знают, что при разделении сети меньшая часть кластера перестаёт принимать записи. Это осознанный выбор согласованности вместо доступности, а не баг.