awesome-everything EN
↑ Обратно к восхождению

Распределённые системы

CAP на практике: согласованность vs доступность при неизбежных разделениях

Суть Разделения сети неизбежны. Единственный выбор во время сбоя — компромисс между согласованностью (корректностью) и доступностью (отзывчивостью). Теорема PACELC расширяет это на штатный режим, где задержка обменивается на согласованность.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на junior-высоте — поверхность
◷ 15 min

Подводный волоконно-оптический кабель между Вирджинией и Дублином разорван глубоководным траулером. В тот же миг задержка между континентами подскакивает с 67 мс до бесконечности из-за 100% потери пакетов. В Вирджинии реплики базы данных продолжают принимать заказы клиентов, увеличивая балансы счетов. В Дублине пользователи нажимают «Купить сейчас» и видят либо бесконечный лоадер, завершающийся ошибкой HTTP 504, либо успешно оформляют заказы, считывая устаревшие балансы до разделения сети — что приводит к массовым овердрафтам. Дежурные инженеры не выбирали разделение; физика навязала его им. Их единственным реальным выбором было то, как их код вел себя в течение этих трех часов сетевого молчания.

Миф о «выборе двух из трех»

Десятилетиями теорему CAP преподавали как простое меню: выберите любые два свойства из согласованности (C), доступности (A) и устойчивости к разделению (P). Это опасное упрощение.

В физической сети вы не можете отказаться от «устойчивости к разделению». Сеть — это общая, несовершенная среда. Кабели рвутся, коммутаторы страдают от переполнения буферов (bufferbloat), маршруты BGP «флапают», а виртуальные сетевые интерфейсы замирают во время миграции гипервизоров. Поскольку разделения неизбежны, P является обязательным.

Таким образом, единственный реальный выбор является бинарным и возникает только при сбое сети:

  • Выбор Согласованности (CP): Отклонить запрос или вернуть ошибку, чтобы гарантировать, что устаревшие или конфликтующие данные никогда не будут прочитаны или записаны. Корректность абсолютна.
  • Выбор Доступности (AP): Принять запрос и вернуть любые локальные данные, которые есть, даже если они устарели или войдут в конфликт с другой частью сети. Отзывчивость абсолютна.
Физическая реальность разделения сети
Сегмент Восток (US-East)
Принимает запись: balance = $100
[Запись сохранена локально]
← [ Связь разорвана ] →100% Потеря пакетов
Сегмент Запад (EU-West)
Пользователь читает balance
Выбор CP: Вернуть Error (503)
Выбор AP: Вернуть Stale ($0)

Формальная калибровка: что на самом деле значат «C» и «A»

Чтобы принимать взвешенные архитектурные решения, senior-инженер должен заглянуть за аббревиатуры и понять точные математические определения, установленные Сетом Гилбертом и Нэнси Линч в их формальном доказательстве гипотезы Брюера:

  1. Согласованность (C) — это линейность (Linearizability): Это очень строгое требование безопасности. Оно требует существования глобального упорядочивания всех операций чтения и записи в реальном времени. Как только запись успешно завершена, любое последующее чтение — в любой точке мира — должно вернуть это новое значение или еще более позднее. Это не позволяет ни одному читателю увидеть устаревшее состояние.
  2. Доступность (A) — это высокая отзывчивость: Каждый исправный узел (non-failing node) в кластере должен возвращать успешный (не содержащий ошибки) ответ на любой полученный запрос. Важно: система не может блокироваться бесконечно или возвращать ошибку (например, таймаут базы данных или HTTP 503 Service Unavailable). Возврат устаревших данных считается полностью «доступным» в смысле CAP.
  3. Устойчивость к разделению (P): Система продолжает функционировать, несмотря на произвольную потерю или задержку сообщений на сетевых границах.

Согласно этому формальному определению, большинство баз данных, заявляющих о «высокой доступности» в маркетинговых материалах, на самом деле являются CP-системами. Например, в кластере консенсуса Raft (таком как etcd или Consul), если разделение сети изолирует лидера от большинства узлов, эти узлы в меньшинстве будут отклонять все записи и чтения для сохранения линейности. Они выбирают корректность вместо отзывчивости — они являются CP.

Теорема PACELC: компромисс при исправной работе

Хотя CAP полезна, у нее есть очевидное ограничение: она описывает поведение системы только во время разделения. В реальных условиях сети исправны 99.9% времени.

Чтобы исправить это, Даниэль Абади сформулировал теорему PACELC в 2012 году. Она расширяет CAP следующим образом:

Если происходит Разделение (Partition) → выбирайте Доступность (A) или Согласованность (C); иначе (Else), при нормальной работе → выбирайте Задержку (Latency) или Согласованность (C).

PACELC заставляет нас оценивать цену наших моделей согласованности во время повседневной, стабильной работы. Если вам требуется строгая согласованность в штатном режиме (EC), каждая запись или чтение должны проходить синхронную координацию (например, ожидание подтверждения от нескольких реплик в разных дата-центрах). Это напрямую добавляет время кругового обхода сети (RTT) к задержке каждого запроса. Если вы выбираете низкую задержку (EL), вы разрешаете репликам обновляться асинхронно, то есть соглашаетесь на eventual consistency при нормальной работе.

База данныхТип по PACELCПоведение при разделении (P/A vs C)Поведение в штатном режиме (E/L vs C)
Google SpannerPC/ECВыбирает Согласованность. Отклоняет записи, если кворум не может быть достигнут.Выбирает Согласованность. Синхронно использует TrueTime и группы Paxos, добавляя незначительную задержку.
Amazon DynamoDBPA/ELВыбирает Доступность. Реплики принимают записи независимо.Выбирает Задержку. Чтения по умолчанию асинхронны (eventually consistent) для достижения задержек менее 10 мс.
MongoDBPC/EC (по умолчанию)Выбирает Согласованность. Меньшинство узлов разжалует primary-узел, блокируя записи.Выбирает Согласованность. По умолчанию направляет все чтения и записи на primary-узел для гарантии линейности.

Реальные сбои в проде и «ложные» разделения

В продакшене разделения сети редко выглядят как чистые, бинарные разрезы, когда половина узлов общается, а половина — нет. Senior-инженер должен проектировать системы с учетом следующих неочевидных сбоев:

  • Асимметричные разделения (Asymmetric Partitions): Узел A может отправлять пакеты узлу B, но ответы от B теряются из-за неисправного порта коммутатора. Системы консенсуса вроде Raft должны использовать механизмы вроде «Pre-Vote», чтобы узел B бесконечно не увеличивал свой term и не срывал работу здоровых узлов.
  • Логические разделения (Высокая задержка): Если JVM, в которой запущена база данных, испытывает 10-секундную паузу Garbage Collection (Stop-the-World), или если фоновая задача перегружает CPU, узел перестает отвечать на heartbeat-запросы. Для своих соседей этот узел выглядит как partitioned. Оставшиеся узлы инициируют новые выборы лидера, хотя старый лидер был полностью исправен, просто временно занят.
  • Налог на разрешение конфликтов в AP: Если вы выбираете AP (как Cassandra или DynamoDB), вам придется платить налог за разрешение конфликтов при записи. Если пользователь изменяет корзину в двух разных разделениях, вашей системе придется сводить эти состояния воедино. Если вы используете простую политику Last-Write-Wins (LWW) на основе физического времени, минимальное расхождение часов приведет к безвозвратной потере корректных записей клиентов. Альтернатива — использование сложных CRDT или векторных часов, что существенно усложняет архитектуру.
Почему это работает

Эрик Брюер пояснил в 2012 году, что классическая формулировка «выберите два свойства» вводит в заблуждение. Цель состоит в том, чтобы максимизировать и согласованность, и доступность, но когда возникает физическое разделение сети, вы обязаны явно управлять компромиссом. Современные системы гибко настраиваются; они позволяют вам задавать write и read concerns для конкретного запроса, динамически перемещая систему по спектру CAP/PACELC.

Выбери лучший вариант

Вы проектируете глобально распределенную систему бронирования билетов с несколькими регионами. Продажа одного и того же места двум клиентам — это катастрофический сбой для бизнеса. Какой архитектурный выбор соответствует теореме PACELC?

Викторина

Согласно формальному математическому доказательству теоремы CAP, представленному Гилбертом и Линч, каково точное определение «Доступности» (Availability)?

Викторина

Почему длительная пауза сборки мусора (GC pause) или высокая загрузка CPU могут вызвать «логическое» разделение сети в CP-кластере консенсуса?

Вспомните перед уходом
  1. 01
    Объясните, почему устойчивость к разделению сети (Partition Tolerance) не является свободным выбором на этапе проектирования распределенной системы.
  2. 02
    В чем ключевое различие между теоремой CAP и теоремой PACELC, и как PACELC применяется в штатном режиме?
Итог

Физические разделения сети неизбежны, поэтому устойчивость к разделению (P) — обязательное требование для распределенных систем. Теорема CAP доказывает, что во время сбоя сети вы обязаны выбирать между согласованностью (C, линейностью) и доступностью (A, успешным ответом любого исправного узла). Системы вроде etcd или Spanner выбирают CP, блокируя работу ради сохранения истины; Cassandra или DynamoDB выбирают AP, сохраняя отзывчивость ценой расхождения состояния. Теорема PACELC расширяет эту модель на штатный режим: даже при здоровой сети вам приходится выбирать между задержкой и согласованностью. Senior-инженер избегает общих слов, калибрует системы по строгим математическим определениям и тонко настраивает кворумы под конкретные задачи.

Продолжить восхождение ↑CAP на практике: тест с выбором ответа
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources4
expand
  1. 01
  2. 02
  3. 03
  4. 04

Trademarks belong to their respective owners. Editorial reference only.