CAP, PACELC и модели консистентности
История про реальные компромиссы распределенных систем
История про реальные компромиссы распределенных систем
История про реальные компромиссы распределенных систем
От теорем к инженерным решениям
Сначала — CAP: C/A/P и корректная трактовка.
Затем — PACELC: профиль под продукт.
Финал — Jepsen, модели и Cassandra.
Во время partition нельзя одновременно обеспечить и C, и A
Для shared-data систем
C: linearizability
A: ответ от живой ноды
P: потеря сообщений
Формальные определения вместо маркетинга
Consistency
Один глобальный порядок
Read-after-write актуален
Это linearizability
Availability + Partition
Availability: ответ без deadline
Partition: потеря сообщений
Вместе конфликтуют с C
Почему это строже, чем «просто одинаковые данные»
Total order совместим с time
Операция выглядит мгновенной
Система как один узел
Desync реплик нарушает гарантию
Слабое по времени, но сильное по обязательности свойство
Живая нода должна ответить
Дедлайна нет, завершение есть
Ждать sync — потеря A
CP часто отвечает error/timeout
От гипотезы к доказательству
1998: Brewer формулирует CAP-гипотезу.
1999: harvest/yield и fault tolerance.
2000: Brewer выводит CAP на PODC.
2002: Gilbert/Lynch доказывают.
Полезно, но слишком грубо
Компромисс возникает при partition
В норме возможны C и A.
Стратегия задается по операциям
Нужны правила деградации
Игнорировать нельзя
Packet loss и zone breaks регулярны
Вопрос — поведение системы
Timeouts дают ложный partition
Нужны runbook-и recovery
Один продукт может сочетать CP и AP-поведение
Деньги часто требуют CP
Ленты допускают AP
API могут вести себя по-разному
Stale read фиксируется явно
Архитектура про градации
Availability = uptime/error budget.
Consistency: eventual → linearizable.
Partition бывает частичным.
Управляем вероятностью и ущербом.
Detect → Decide → Recover
Detect / Decide
Симптомы: latency, majority, heartbeats
Policy: fail-fast или stale
Ограничения: read-only/degrade
Recover
Reconciliation между репликами
Conflict resolution и compensation
Метрики: lag, conflicts, recovery
Partition часто начинается с timeout
Slow network выглядит как partition
Ждать дольше помогает C
Отвечать быстрее помогает A
Timeout/retry — часть CAP
Путаница терминов ломает архитектуру
C в ACID
Бизнес-правила и инварианты
Баланс, FK, схемы
Транзакционная корректность
C в CAP
Линеаризуемость в distributed system
Узлы видят несовместимые результаты
Реплики и сеть под сбоями
Soft state, eventual consistency
Временная рассогласованность ради A.
Soft state меняется сам.
Eventual convergence без новых writes.
Это другой профиль гарантий.
Почему теорема строгая
C = atomic consistency.
A: healthy node отвечает.
P: произвольная потеря сообщений.
Read/write объект не даст A+C.
Две ноды, contradiction
Пусть есть A + atomic C
G1 и G2 не обмениваются сообщениями
Write в G1, read из G2
A требует ответ; C — write
Часы не отменяют CAP
Clocks и deadlines помогают.
Потеря сообщений сохраняет A/C conflict.
Timeouts только обнаруживают проблему.
Поведение на инциденте выбираем.
Опишите критичные операции
Согласуйте отказ и деградацию
Свяжите timeout/retry с CAP
Подготовьте reconciliation заранее
CAP — это управляемая деградация, а не теоретическая головоломка.
PACELC добавляет вопрос «что делать, когда сбоев нет»
P-блок — При partition выбираем A или C.
ELSE-блок — В норме выбираем L или C.
Почему важно — Большинство решений — в мирном режиме.
if P then A/C else L/C
P: availability или consistency
ELSE: latency или consistency
Trade-off есть всегда
Лучше объясняет современные БД
CAP молчит про штатный режим
Partition редок; Cassandra eventual.
Ответ: latency и пропускная способность.
Cross-region sync повышает p99.
PACELC показывает мирный выбор.
Наибольшая архитектурная боль происходит именно здесь
Глобальный порядок требует координации
Координация бьет по p95/p99
Eventual/causal меняет логику
Считаем цену delay vs error
PA/EL, PC/EC, PA/EC, PC/EL
A-профили
PA/EL: A при P, L normally.
PA/EC: A при P, C normally.
C-профили
PC/EC: C при P и normally.
PC/EL: C при P, L normally.
Формализуйте профиль в ADR/SLO.
Типичный выбор для high-scale контентных сценариев
При partition продолжает отвечать
В норме оптимизирована под latency
Примеры: Cassandra/DynamoDB/Riak
Нужны compensation mechanisms
Подходит, когда ошибка чтения/записи дороже задержки
Partition блокирует часть операций
В норме тоже ставка на C
Примеры: Spanner-like системы
Домены: payments, ledger, limits
Доступность на инциденте; C в норме
Partition: не прерывать сервис
Норма: сильнее consistency
Зависит от quorum/read concern
Staleness только в аварии
Строго при сбоях, быстро при нормальной сети
Partition: часть запросов reject
Норма: низкая latency
Сложный routing/failover
Ниша: strict incident policy
Не «какая БД модная», а «какая ошибка недопустима»
Приоритет C
Платежи и проводки.
Остатки/лимиты без oversell.
Юридические журналы и аудит.
Приоритет L/A
Ленты и рекомендации.
Поиск с допустимым drift.
Near-real-time аналитика.
PACELC должен попадать в метрики команды
Фиксируем p95/p99 и stale reads
Разделяем downtime и freshness
Write: latency, lag, conflicts
Read: lagging share, version age
CAP: авария; PACELC: авария + норма.
Главный выбор часто в else-ветке.
Категория следует из цены бизнес-ошибки и SLA.
Решение обязательно валидировать тестами и наблюдаемостью.
Эксперимент подтверждает инженерный компромисс.
От документации к проверяемым гарантиям
Что это — Тестирование корректности под сбоями.
Что делает — Генерирует операции, инжектит сбои и проверяет историю.
Почему важно — Отделяет гарантии от маркетинга.
Баги видны на сбоях
Проверяет partition/crash/clock skew.
Находит lost writes и atomicity bugs.
Вендоры уточняют гарантии.
Команда видит риски до внедрения.
Setup → Generate → Nemesis → Record → Check
Setup: кластер и expected model
Generate: concurrent read/write/CAS
Nemesis: failures and anomalies
Record + Check: counterexample
И почему именно они ломают «почти корректные» системы
Сетевые сценарии
Полный partition между группами.
Асимметричная потеря и видимость.
Высокий jitter, нестабильные связи.
Процессные/временные
Crash/restart процессов или лидеров.
Clock skew и time-sync drift.
Наслаивающиеся сценарии.
Где обещания расходятся с реальностью
Lost writes при failover/split-brain.
Read-your-writes нарушен; stale read.
Транзакционные аномалии под concurrency.
«Strong consistency» без формальной модели.
Serializable (RDBMS) и Linearizable (Distributed)
Transactional ветка — Изоляция и допустимые аномалии.
Distributed ветка — Глобальный порядок read/write.
Вершина — Strict Serializable объединяет обе оси.
Похожие слова, разные гарантии
Serializable
Эквивалентно serial execution
Порядок не обязан совпадать с time
Фокус: transaction isolation
Linearizable
Одна commit-точка операции
Порядок уважает real time
Фокус: replicated read/write
Гарантия должна стоить ошибки
Eventual — когда stale допустим
Causal — для причинных цепочек
Linearizable — для read/write truth
Strict Serializable — для инвариантов
1) Формализуйте инварианты и недопустимые бизнес-ошибки.
2) Опишите partition mode по операциям.
3) Выберите PACELC-профиль и latency/consistency budget.
4) Зафиксируйте целевую модель консистентности формально.
5) Проверяйте chaos/Jepsen до критичной нагрузки.
Компромисс подтверждает эксперимент.
Bigtable + Dynamo, tunable consistency и AP-профиль
Происхождение — Bigtable: wide-column и LSM write path. Dynamo: hashing, gossip, peer-to-peer.
Классификация — CAP: AP. PACELC: PA/EL — partition availability, normal low latency.
Практика — Сильная сторона — tunable consistency: ANY/ONE → QUORUM/ALL/SERIAL.
Гарантия зависит от R/W levels
Writes: ANY, ONE, QUORUM, ALL
Reads: ONE, QUORUM, ALL
W+R>RF повышает latest read.
QUORUM — частый production balance
LSM + ring + repair
Путь записи и хранения
Commit Log -> MemTable -> SSTable (immutable files).
Compaction чистит версии.
LSM оптимизирован под writes.
Распределение и устойчивость
Consistent hashing + vnodes.
Gossip без мастера.
Repair-механизмы для сходимости.
CAP: https://system-design.space/chapter/cap-theorem
PACELC: https://system-design.space/chapter/pacelc-theorem
Модели консистентности (Jepsen): https://system-design.space/chapter/jepsen-consistency
Cassandra: https://system-design.space/chapter/cassandra
Все 4 исходные главы system-design.space в одном месте.