Надёжность распределённых систем: карта

Навигатор по надёжности распределённых систем: консенсус, согласованность, атомарность и транзакции, гарантии доставки сообщений и устойчивость под нагрузкой — как это связано и в каком порядке разбираться

Надёжность распределённой системы — не одна тема, а слоёный пирог: договориться о едином состоянии (консенсус), решить, насколько строгая нужна согласованность, обеспечить атомарность изменений, гарантировать доставку сообщений и выстоять под нагрузкой. Убери любой слой — и «надёжность» рассыплется на удачу: система, где узлы не договорились о лидере, отлично теряет данные даже при идеальном retry; система с идемпотентными консьюмерами, но без учёта изоляции, спокойно принимает решения по грязным данным.

Это хаб-навигатор поверх нескольких серий и одиночных статей: он связывает слои в одну карту и задаёт порядок, в котором в них стоит разбираться. Карта живая: нижние четыре слоя — консенсус, согласованность, транзакции, доставка — ведут на написанные статьи, а верхний, про устойчивость под нагрузкой, разбирает серия «System design: resilience» вместе со своей картой защиты от перегрузкиготовится, с 8 сентября. Ссылки, ведущие на ещё не вышедшие статьи, сами показывают дату выхода, так что карта отражает форму темы целиком, а не только то, что успели написать.

Ретрофутуристский разрез пятиярусной ступенчатой платформы в стиле «Полдень», читается снизу вверх: ряд фигур, взявшихся за руки над сеткой связей (консенсус); весы, на одной чаше груда кубов, на другой всего несколько (согласованность); шестерни вокруг запертого несгораемого ящика (атомарность и транзакции); светящиеся трубы, несущие конверты по ветвящимся пунктирным маршрутам (доставка); манометр и тяжёлый предохранительный клапан под давящей сверху стрелкой (устойчивость под нагрузкой). Слева — выноски к каждому ярусу, в правом верхнем углу компас-роза

В статье

Что связывает этот хаб

Слои надёжности, снизу вверх — каждый опирается на предыдущий:

flowchart BT A["Консенсус
узлы договариваются о состоянии"] --> B["Согласованность
строгая vs eventual"] B --> C["Атомарность и транзакции
целостность изменений"] C --> D["Доставка сообщений
гарантии в очередях и логах"] D --> E["Устойчивость под нагрузкой
деградация без обвала"]

flowchart BT
  A["Консенсус
узлы договариваются о состоянии"] --> B["Согласованность
строгая vs eventual"] B --> C["Атомарность и транзакции
целостность изменений"] C --> D["Доставка сообщений
гарантии в очередях и логах"] D --> E["Устойчивость под нагрузкой
деградация без обвала"]
Слои надёжности распределённой системы: каждый опирается на нижний
  • Консенсус — как узлы договариваются о едином состоянии и кто «главный»;
  • Согласованность — строгая vs eventual, где какая нужна и чем платим;
  • Атомарность и транзакции — целостность изменений, в том числе поверх нескольких хранилищ;
  • Доставка сообщений — какие гарантии дают очереди и логи и как их не растерять;
  • Устойчивость под нагрузкой — деградация без обвала, изоляция отказов, восстановление.

Консенсус и согласованность

В основании — вопрос, на который не бывает бесплатного ответа: как несколько узлов приходят к единому мнению о состоянии, если сеть, диски и сами узлы могут отказать. Обзорный тур по алгоритмам (Paxos, Raft, ISR, кворумы) через интерактивный симулятор — Consensus Landscape: тур по алгоритмам консенсуса. Именно консенсус стоит за Raft-группами JetStream в NATS (persistence и репликация — в отличие от Core NATS, который работает иначе), за выбором лидера партиции в Kafka и за кворумными записями в БД — то, что кажется «просто репликацией», на деле держится на нём.

Над консенсусом — выбор уровня согласованности, и здесь фундаментальное ограничение: при сетевом разделении нельзя одновременно иметь и мгновенную согласованность, и доступность. Как это формулируют CAP и его уточнение PACELC (что выбираем даже когда сеть в порядке — задержку или согласованность) — CAP и PACELC: чем платим за согласованностьСкоро. А как выбирать уровень под конкретные данные — строгую, eventual или пакетную, по бюджету устаревания — Согласованность данных: строгая vs «в итоге».

Атомарность и транзакции

Согласились о состоянии — теперь надо менять его целостно. Внутри одной СУБД это транзакции и уровни изоляции; и первое, что стоит понять, — какие аномалии живут на каждом уровне и почему «просто SERIALIZABLE везде» не бесплатно: Транзакции: уровни изоляции и аномалии. Практика на PostgreSQL — Транзакции: реляционная практика (PostgreSQL); как это выглядит в KV/документных хранилищах, где гарантии слабее, — Транзакции: KV и документные (Redis/Mongo/Scylla); а чем «транзакция» в брокере отличается от транзакции в СУБД — Транзакции: брокеры (RabbitMQ/Kafka). Сводит выбор воедино Транзакции: мульти-хранилище, бенчмарк и карта решений.

Как только изменение пересекает границу одного хранилища, классическая транзакция кончается. Двухфазный коммит существует и работает — в пределах одной СУБД или датацентра его применяют (XA, prepared transactions). Но он блокирующий: если координатор упал между prepare и commit, участники сидят с удержанными блокировками, пока кто-то не вмешается. Через ненадёжную сеть между сервисами это связывает их доступность в общий узел отказа, поэтому в распределённых системах чаще идут другим путём. Здесь работают событийные паттерны: Saga: распределённые транзакции без 2PC (локальные транзакции + компенсации) и Transactional Outbox/Inbox (атомарно записать изменение и факт о нём, а наружу отдать надёжным событием). Оба держатся на идемпотентности потребителя — фундаменте, разобранном отдельно: Гарантии доставки и идемпотентность (effectively-once).

Доставка сообщений

Событие мало произвести — его надо надёжно доставить, и гарантия здесь не свойство брокера вообще, а свойство конкретной конфигурации. В RabbitMQ это durability очереди, publisher confirms, ручной ack и DLQ — RabbitMQ: durability, confirms, ack, DLQ. В NATS постоянство и at-least-once появляются только с JetStream — NATS JetStream: persistence и гарантии доставки. В Kafka строгий exactly-once — отдельный механизм транзакций поверх репликации — Kafka: exactly-once и транзакцииготовится, с 7 августа. Как эти гарантии соотносятся между собой и почему сквозной exactly-once недостижим без идемпотентности — снова Гарантии доставки и идемпотентность.

Отдельный угол — когда сами события становятся источником правды и контрактом: Event Sourcing: когда история важнее состояния и Контракты событий и schema evolution. Вся событийная тема связана в собственной карте — Messaging: карта выбора и эксплуатации.

Устойчивость под нагрузкой

Верхний слой — как система ведёт себя, когда всё уже согласовано и доставляется, но нагрузка растёт, а зависимости отказывают. Ядро — паттерны устойчивости: circuit breaker, retry с backoff, timeout, bulkhead — Паттерны устойчивости: circuit breaker, retry, timeout, bulkheadготовится, с 14 сентября. Чтобы система не захлебнулась, — ограничение частоты и сброс нагрузки: Rate limiting и throttlingготовится, с 11 сентября и Backpressure и load sheddingготовится, с 16 сентября. Почему очередь под нагрузкой ведёт себя нелинейно и как оценивать ёмкость — Теория очередей и планирование ёмкостиСкоро.

Координация под отказами — распределённые блокировки и лизы (кто сейчас владеет ресурсом, что при потере лидера) — Распределённые блокировки и координацияготовится, с 15 сентября, и общее хранилище конфигурации/координации на etcd/Consul/Vault — Распределённая конфигурация: etcd, Consul, Vault. И, наконец, эксплуатационная сторона: как пережить катастрофу (RPO/RTO) — Disaster recovery: RPO, RTO, стратегииготовится, с 18 сентября — и как разбирать инциденты без поиска виноватых — Инциденты и постмортемыготовится, с 20 сентября.

С чего начать

Соседние карты

  • Messaging: карта выбора и эксплуатации — если вопрос не «как обеспечить надёжность вообще», а «каким брокером и с какими гарантиями доставлять события».
  • Данные: карта хранилищ и подходовготовится, с 22 сентября — где и как хранить данные; надёжность хранения — её слой.
  • Consensus Landscape — если хочется спуститься на уровень алгоритмов под всей репликацией и кворумами.
  • Сквозной кейс: собираем систему лунной базы — как эти слои складываются в одну работающую систему на едином сценарии.

Обсуждение в Telegram

Присоединиться →

Комментарии