Основные понятия
Теорема CAP
Компромиссы между согласованностью и доступностью в распределенных системах
Что такое теорема CAP?
В основе теоремы CAP лежит утверждение, что в распределенной системе одновременно можно обеспечить только два из трех свойств:
- Согласованность (Consistency): все узлы видят одни и те же данные в один и тот же момент времени. Если запись попала на один узел, все последующие чтения с любого узла вернут обновленное значение.
- Доступность (Availability): каждый запрос к рабочему узлу получает ответ, пусть даже он не гарантирует самую свежую версию данных.
- Устойчивость к разделению (Partition Tolerance): система продолжает работать, даже если между узлами теряются сообщения или в случае отказа части узлов (например, из-за разрыва сети).
Важно понимать, что согласованность в теореме CAP отличается от ACID-согласованности традиционных СУБД.
В реальных распределенных системах устойчивость к разделению - обязательное требование: сетевые сбои неизбежны, и система должна их переживать.
Поэтому практический выбор сводится к тому, на что делать упор при разделении сети: на согласованность или на доступность.
Пример для понимания теоремы CAP
Представьте, что ваш сайт работает на двух серверах - в Москве и Новосибе. Пользователь обновляет публичный профиль (например, отображаемое имя), и обычный сценарий выглядит так:
- Пользователь А подключается к ближайшему серверу (в Москве) и меняет имя.
- Обновление реплицируется на сервер в Новосибе.
- Пользователь B в Новосибе открывает профиль пользователя А и видит новое имя.
Проблемы начинаются, когда связь между серверами в Москве и Новосибе пропадает. Теперь нужно решить, что делать, когда пользователь B пытается открыть профиль пользователя А:
- Вариант A: вернуть ошибку, потому что нет уверенности в актуальности данных - приоритет согласованности.
- Вариант B: показать потенциально устаревшие данные - приоритет доступности.
В большинстве случаев лучше показать старые данные, чем ошибку, поэтому выбирают доступность.
Когда выбирать согласованность
Есть классы систем, где согласованность важнее доступности:
- Бронирование билетов: нужно исключить двойную продажу одного и того же места при сетевых проблемах.
- Складской учет в e-commerce: нельзя позволить разным узлам продавать последний товар одновременно.
- Финансовые системы: критично показывать точный и актуальный баланс пользователя и список транзакций.
Когда выбирать доступность
В большинстве систем допустима временная несогласованность, поэтому приоритет отдается доступности. Достаточно добиться согласованности в конечном счете (Eventual Consistency) - система синхронизируется, но это может занять секунды или минуты:
- Социальные сети: никто не пострадает, если аватар обновится с задержкой.
- Контентные платформы: устаревшее описание фильма на несколько минут не критично.
- Сервисы наподобие 2ГИС: если у компании изменилось расписание, лучше показывать старое, чем спрятать карточку компании.
Главный вопрос, который можно задать себе: насколько критично, если пользователи ненадолго увидят несогласованные данные? Если критично - выбирайте согласованность. Если нет - доступность.
Теорема CAP на собеседованиях по System Design
Обычно обсуждение на интервью выглядит так:
- Согласование функциональных требований.
- Формулирование нефункциональных требований.
При обсуждении нефункциональных требований сразу определитесь с компромиссом по CAP: что важнее - согласованность или доступность.
Если приоритет - согласованность, в архитектуре могут появиться:
- Распределенные транзакции (Distributed Transactions): двухфазная фиксация (Two-Phase Commit) и прочие механизмы синхронизации нескольких хранилищ данных (например, базы данных и кэша), увеличивающие задержки.
- Решения с одним узлом (Singe Node Solutions): ограниченная масштабируемость ради единого источника истины.
- Технологии: традиционные СУБД (PostgreSQL, MySQL), Google Spanner, DynamoDB в режиме строгой согласованности.
Если приоритет - доступность, подойдут другие подходы:
- Множество реплик: асинхронные обновления и чтение с реплик для обеспечения высокой доступности.
- Change Data Capture: асинхронная отсылка изменений в реплики, очереди и кэш. Основной экземпляр базы данных (Primary Database) остается доступным, в то время как остальные части системы становятся согласованными с течением времени.
- Технологии: Cassandra, DynamoDB в конфигурации нескольких зон доступности, кластеры Redis.
Многие современные распределенные базы позволяют настраивать уровень согласованности под конкретный сценарий. Важно понять, что нужно в вашем случае.
Расширенные аспекты теоремы CAP
Если вы претендуете на уровень Junior или Middle, материалов выше обычно достаточно. Дальше идут более продвинутые идеи, которые пригодятся на уровнях Senior и выше.
В реальности одной системе часто нужны и согласованность, и доступность - но для разных частей. Например:
- Ticketmaster: бронирование мест требует строгой согласованности, тогда как просмотр информации о событии может быть ориентирован на доступность.
- Tinder: совпадения (Matching) можно фиксировать согласованно, но для просмотра профилей можно отдать приоритет доступности.
Уровни согласованности
Обсуждая согласованность в теореме CAP, обычно подразумевают сильную согласованность (Strong Consistency), при которой все чтения отражают последнюю запись.
Однако понимание различных уровней согласованности поможет вам принимать более взвешенные решения при проектировании:
- Сильная согласованность (Strong Consistency): все чтения возвращают самую последнюю запись; нужна для банковских балансов и критичных данных.
- Причинная согласованность (Causal Consistency): связанные события отображаются всем пользователям в одном порядке, сохраняя причинно-следственные связи (например, пост в соцсети и комментарий к нему).
- Чтение своей записи (Read-your-own-writes Consistency): пользователь сразу видит собственные изменения, даже если остальные видят старые данные. Исключает случай, когда пользователь не видит недавних изменений и полагает, что они не применились.
- Согласованность в конечном счете (Eventual Consistency): система сходится со временем; характерно для DNS и многих распределенных хранилищ данных.
Выводы
Теорема CAP помогает структурировать ваши архитектурные решения на интервью.
Но не стоит ее переусложнять, просто ответьте на вопрос: "Каждое чтение обязано получать последнюю запись?" Если да - выбирайте согласованность. Если нет - доступность.