Лабораторная 02: Один узел — ещё не система
Подключите реплицируемое хранилище с готовой реализацией консенсуса. Остановите лидера и разделите сеть.
Код стенда, установка и шаблон отчёта
Лабораторная 2. Большинство, живое меньшинство и возврат реплики
Продолжите сервис Lab1 на том же трёхузловом etcd. Цель — отделить безопасность подтверждённых операций от доступности, а смену лидера от восстановления избыточности. Требуются исправленный Lab1, понимание кворума и лекция о Raft. Длительность около 90 минут — ориентир автора.
Запуск
После подготовки по README, из корня репозитория:
PYTHONDONTWRITEBYTECODE=1 /tmp/ds-course-venv/bin/python labs/distributed-systems/runner.py --lab 2 --solution starter --report /tmp/lab02.json
Используется собственный уникальный Compose project. Три настоящих etcd member используют Raft; мы не пишем и не подменяем консенсус моделью. Python обращается к JSON gateway. Для сверки доступен --solution reference; failure-сценарии общие.
Задание
- Нарисуйте две сети: peer для репликации и control для HTTP. Укажите, какой DNS alias доступен только в peer-сети. Докажите по сценарию, что клиент добирается до изолированного живого процесса.
- Проверьте клиентский выбор endpoint и timeout в
common.py. Объясните, почему переключение endpoint не даёт права заменить linearizable read устаревшим чтением. Повтор неопределённой записи сохраняет Idempotency-Key. - Разделите три интервала в отчёте: наблюдение нового лидера, первый успешный запрос клиента, возвращение третьей актуальной копии. Не называйте один из них автоматически «временем восстановления» без определения.
Три сценария
- Остановка лидера. Runner находит лидера через настоящий
etcdctl endpoint status, останавливает его контейнер, повторяет запись через оставшиеся endpoint и читает ранее подтверждённую задачу. Затем запускает прежний узел. - Живое меньшинство. У follower отключается только peer network.
/versionи control-сеть остаются доступны. Запись и linearizable read через строго этот endpoint не должны получить успешное подтверждение; явно запрошенное serializable чтение ранее записанного значения может пройти. Большинство продолжает принимать задачи. Peer-сеть восстанавливается с исходным alias и IP. - Отставшая реплика. Follower остановлен; большинство принимает восемь задач. После возврата проверяются их чтение через этот member и рост applied index. Этот короткий прогон показывает догонку журнала; он не вынуждает установку snapshot.
Инвариант: ранее подтверждённые задачи сохраняются при заявленных отказах; живое меньшинство не подтверждает новую запись без большинства. Неполученное подтверждение не доказывает, что операция никогда не применится после восстановления: отчёт сохраняет судьбу probe отдельно. Доступность зависит от большинства, сети, дисков и клиентского deadline.
Что сдавать
- JSON отчёт, схему сетей и небольшую историю
invoke/response/unknownдля ключей до, во время и после разделения. - Доказательства, что меньшинство было живым: ответ
/version, изолированный endpoint, ошибка consensus-операции, успешная запись большинства. - Applied index до/после; объяснение, почему index сам по себе не доказывает правильный пользовательский результат.
- ADR о выборе семантики чтения и отчёт с раздельными интервалами. Сохраните количество попыток и ошибок, включая timeout.
Чтение и защита
Основные источники: Raft, разделы о leader election, safety и log replication; Dynamo, чтобы сравнить другой выбор доступности; etcd API guarantees. Исследовательские деки Raft, Dynamo и Spanner поддерживают обсуждение кворумов и чтений, но их локальные адреса не являются публичными страницами курса.
Объясните: зачем разделять сетевой отказ и stop процесса; чем serializable range etcd отличается от serializable транзакционной изоляции; почему наличие лидера недостаточно для успешной операции; какую гарантию вы потеряете, если после timeout прочитаете устаревшую реплику без обозначения этого режима.
Восстановление и границы
Runner возвращает peer-сеть в finally и удаляет только свой проект. После принудительного SIGKILL используйте сохранённый compose.env и README; чужие сети не трогайте. Все контейнеры находятся на одном компьютере. Мы проверяем crash/partition и короткую догонку, не Byzantine-модель, не отказ всего дата-центра и не восстановление после уничтожения большинства дисков.