Надёжность распределённой системы — не одна тема, а слоёный пирог: договориться о едином состоянии (консенсус), решить, насколько строгая нужна согласованность, обеспечить атомарность изменений, гарантировать доставку сообщений и выстоять под нагрузкой. Убери любой слой — и «надёжность» рассыплется на удачу: система, где узлы не договорились о лидере, отлично теряет данные даже при идеальном retry; система с идемпотентными консьюмерами, но без учёта изоляции, спокойно принимает решения по грязным данным.
Это хаб-навигатор поверх нескольких серий и одиночных статей: он связывает слои в одну карту и задаёт порядок, в котором в них стоит разбираться. Карта живая: нижние четыре слоя — консенсус, согласованность, транзакции, доставка — ведут на написанные статьи, а верхний, про устойчивость под нагрузкой, разбирает серия «System design: resilience» вместе со своей картой защиты от перегрузкиготовится, с 8 сентября. Ссылки, ведущие на ещё не вышедшие статьи, сами показывают дату выхода, так что карта отражает форму темы целиком, а не только то, что успели написать.
В статье
- Что связывает этот хаб
- Консенсус и согласованность
- Атомарность и транзакции
- Доставка сообщений
- Устойчивость под нагрузкой
- С чего начать
- Соседние карты
Что связывает этот хаб
Слои надёжности, снизу вверх — каждый опирается на предыдущий:
узлы договариваются о состоянии"] --> 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 сентября.
С чего начать
- Фундамент. Consensus Landscape → Согласованность: строгая vs eventual → Транзакции: изоляция и аномалии.
- Событийный угол. Гарантии доставки и идемпотентность → Outbox/Inbox → Saga.
- Эксплуатация. Паттерны устойчивостиготовится, с 14 сентября → Backpressure и load sheddingготовится, с 16 сентября → Disaster recoveryготовится, с 18 сентября → Инциденты и постмортемыготовится, с 20 сентября.
Соседние карты
- Messaging: карта выбора и эксплуатации — если вопрос не «как обеспечить надёжность вообще», а «каким брокером и с какими гарантиями доставлять события».
- Данные: карта хранилищ и подходовготовится, с 22 сентября — где и как хранить данные; надёжность хранения — её слой.
- Consensus Landscape — если хочется спуститься на уровень алгоритмов под всей репликацией и кворумами.
- Сквозной кейс: собираем систему лунной базы — как эти слои складываются в одну работающую систему на едином сценарии.
Комментарии