CAP - это аббревиатура от Consistency (согласованность), Availability (доступность) и Partition tolerance (устойчивость к разделениям сети). Теорему впервые сформулировал в 2000 году Эрик Брюэр, а позже она была строго доказана.
Суть: в условиях сетевых сбоев распределённая система может обеспечить только две из трёх этих характеристик одновременно. Хотите всё сразу - невозможно. Что-то всегда придётся выбирать, а значит - чем-то жертвовать.
Чтобы разобраться, что за выбор такой трагичный, сначала расшифруем каждое из свойств.
Все узлы системы в любой момент времени видят одни и те же данные. Если вы записали информацию в одну ноду, другой пользователь не должен увидеть старое значение. Это ощущается как работа с единым источником правды.
Пример: в банковском приложении вы перевели деньги, и сразу видите новый баланс. Не через 5 секунд. Не «у меня 1000, у тебя 800». Сразу и у всех - 900.
Каждый запрос от клиента получает ответ - успешный или с ошибкой. То есть система отвечает всегда, даже если часть узлов недоступна. Важно: это не значит, что данные всегда актуальны - просто вы получите какой-то ответ.
Пример: вы открываете пост в соцсети, и он загружается. Пусть даже там старые комментарии - но что-то отображается.
Система продолжает работать даже при потере связи между частями. Узлы могут быть изолированы друг от друга, но система не падает. В современных интернет-приложениях такое поведение - скорее необходимость, чем опция.
Пример: половина дата-центров отвалилась, но другая продолжает принимать заказы. После восстановления связи всё синхронизируется.
Когда между частями системы пропадает связь (а это рано или поздно случится), вы стоите перед выбором:
Всё зависит от вашей предметной области. Вот несколько сценариев:
Если важнее не навредить, чем работать всегда - выбирают этот вариант. Лучше отказать в обслуживании, чем отдать кривые данные.
Подходит для:
- Банковских систем
- Финансовых транзакций
- Учёта и биллинга
Пример: вы не сможете снять деньги, если что-то пошло не так, но баланс никогда не «сломается».
Если важнее всегда отвечать, даже ценой временной несогласованности - выбирают AP. Когда сбой устранят, данные синхронизируются.
Подходит для:
- Социальных сетей
- Онлайн-карт и поиска
- Рекламных систем
Пример: вы поставили лайк, а он появился через минуту. Не критично.
Этот режим возможен только при отсутствии сбоев связи, то есть в централизованных или локальных системах. В распределённых системах он практически нереален.
Пример: SQL-база на одном сервере. Всё стабильно - пока не упал интернет или питание.
Если вы выбираете базу данных или строите микросервисную архитектуру - CAP-теорема должна быть у вас в голове.
Это особенно важно для архитекторов программного обеспечения, DevOps- и SRE-инженеров, которые проектируют распределённые системы, обеспечивают их надёжность и поддерживают масштабируемость в проде.
MongoDB, Cassandra, Couchbase - ориентированы на AP, они «терпимы» к временной несогласованности.
Zookeeper, etcd, PostgreSQL в кластере - ближе к CP, особенно в чувствительных зонах.
Redis (standalone), локальные SQLite-базы - скорее CA, но они не масштабируются горизонтально.
Важно понимать: CAP-теорема не запрещает строить крутые системы. Она просто требует определиться с приоритетами. И именно это решение - архитектурное, бизнесовое и продуктовое - лежит в основе устойчивых решений.
Например, в одном и том же проекте разные сервисы могут быть спроектированы по разным принципам:
- авторизация - строго CP (лучше не пустить, чем допустить ошибку);
- аналитика - AP (данные догонят);
- загрузка изображений - доступность важнее всего.