CAP, PACELC и модели согласованности
↑ 6.1 Масштабирование и надёжность данных · ← Предыдущая · → Следующая
Зачем это на собесе
Теория распределённых систем нужна для обоснования выбора хранилища и объяснения компромиссов.
CAP
В распределённой системе при сетевом разделении (Partition) нужно выбрать между:
- C — Consistency (линеаризуемость): каждое чтение видит последнюю запись;
- A — Availability: каждый живой узел отвечает на запрос.
Partition tolerance обязательна (сети ненадёжны), поэтому практически выбор CP или AP:
| Класс | Поведение при разделении | Примеры |
|---|---|---|
| CP | отвергает запросы на отстающей части, чтобы сохранить согласованность | ZooKeeper, etcd, Consul, HBase, MongoDB (majority), Spanner, CockroachDB |
| AP | продолжает отвечать, возможны расхождения (разрешаются позже) | Cassandra, DynamoDB (по умолчанию), Riak, CouchDB |
Замечание: CAP описывает только поведение при разделении. «CA» в реальной распределённой системе не существует; одиночный узел — не распределённая система.
PACELC
Расширение CAP: если есть разделение (P) — выбор между A и C; иначе (Else) — между задержкой (Latency) и согласованностью (C).
PA/EL: Cassandra, DynamoDB — доступность при разделении и низкая задержка в норме
PC/EC: HBase, Spanner, MongoDB (majority) — согласованность всегда, выше задержка
PA/EC: MongoDB по умолчанию (в разных конфигурациях)
PC/EL: PNUTSПочему важно: даже без сбоев синхронная репликация увеличивает задержку, и за сильную согласованность платят всегда.
Модели согласованности
От сильной к слабой:
| Модель | Гарантия |
|---|---|
| Линеаризуемость (strong) | система ведёт себя как один узел; чтение видит последнюю запись в реальном времени |
| Последовательная (sequential) | единый порядок операций, согласованный с порядком каждого клиента |
| Причинная (causal) | причинно-связанные операции видны в одном порядке всем |
| Read-your-writes | клиент видит свои записи |
| Monotonic reads | повторное чтение не возвращает более старое значение |
| Eventual | при отсутствии новых записей все реплики сойдутся |
Изоляция транзакций (ACID, одиночная БД) — другая ось: Serializable, Snapshot и т. д. Strict serializability = сериализуемость + линеаризуемость (Spanner).
Кворумы
При N репликах, записи на W и чтении с R реплик: если R + W > N — чтение пересекается с последней записью (сильнее согласованность). Пример: N = 3, W = 2, R = 2. Настройка в Cassandra (QUORUM, ONE, ALL), DynamoDB (ConsistentRead), MongoDB (w: majority, readConcern).
Разрешение конфликтов
- LWW (last write wins) по времени: просто, теряет данные, зависит от синхронизации часов;
- векторные часы, версионирование;
- CRDT: структуры, автоматически сходящиеся (счётчики, множества, текст);
- слияние в приложении;
- консенсус (Raft, Paxos) для линейной согласованности: лидер и кворум; основа etcd, Consul, CockroachDB, Kafka KRaft.
Практика
- банки, склад, бронирование — сильная согласованность (CP, транзакции);
- ленты, лайки, счётчики, каталоги — допускается eventual;
- смешанный подход: критичные данные в ACID-БД, остальное в AP/кэшах;
- обеспечивайте идемпотентность и компенсации (саги) там, где есть eventual consistency;
- явно проектируйте, что пользователь увидит при лаге репликации.
Вопросы с ответами
Что говорит теорема CAP?
При сетевом разделении распределённая система не может одновременно обеспечить линеаризуемость и доступность каждого узла; приходится выбирать C или A.
Чем PACELC полезнее CAP?
Учитывает и нормальную работу: даже без разделения есть компромисс между задержкой и согласованностью (синхронные реплики дают согласованность ценой задержки).
Что значит eventual consistency?
Если новые обновления прекращаются, со временем все реплики придут к одному значению; в промежутке возможны устаревшие чтения.