Теорема CAP утверждает: в распределённой системе при сетевом разделении нельзя одновременно гарантировать согласованность, доступность и устойчивость к разделению. На практике это правило помогает понять, чем придётся пожертвовать при проектировании хранилища данных и распределённого приложения.
Эту идею часто связывают с облачными сервисами, NoSQL-базами и микросервисами. Но суть шире: как только данные живут на нескольких узлах, а связь между ними может нарушаться, выбор между свойствами системы перестаёт быть теорией и становится инженерным решением.
Содержание статьи
Что означает CAP в распределённых системах
CAP — это три свойства распределённой системы: Consistency, Availability и Partition Tolerance, то есть согласованность, доступность и устойчивость к сетевому разделению. Теорема говорит не о том, что система всегда имеет только два свойства из трёх, а о том, что в момент разделения сети приходится выбирать между согласованностью и доступностью.
Это уточнение важно. Если между узлами нет проблем со связью, система может вести себя как согласованная и доступная. Ограничение проявляется тогда, когда часть узлов перестаёт видеть другую часть сети, но продолжает работать.
Именно поэтому теорема CAP так часто обсуждается в контексте облачной инфраструктуры. В распределённой среде сетевые сбои, задержки и потеря связи между узлами не считаются редким исключением.
Что такое согласованность в CAP
Согласованность означает, что все узлы возвращают одно и то же актуальное значение данных после успешной записи. Если один клиент изменил запись, другой клиент не должен увидеть старую версию на другом узле.
В CAP под согласованностью понимается довольно строгое поведение. Чтение после записи должно давать единый результат независимо от того, к какому доступному узлу обращается клиент.
Представим заказ в интернет-магазине. Если оплата уже проведена, система не должна на одном узле показывать статус «оплачен», а на другом — «ожидает оплаты». Для таких сценариев расхождение данных быстро превращается в проблему бизнес-логики, а не просто в техническую особенность.
Что такое доступность в CAP
Доступность означает, что каждый запрос к работающему узлу получает ответ. Ответ может быть не самым свежим с точки зрения данных, но система не должна молчать или отказывать без необходимости.
Здесь акцент делается именно на ответе. Если узел доступен, он должен обработать чтение или запись в рамках выбранной модели работы системы.
Для некоторых приложений это критично. Например, сервис телеметрии, логи или лента событий часто важнее держать доступными даже при временном расхождении копий данных. Иначе часть информации просто не попадёт в систему вовремя.
Что такое устойчивость к разделению
Устойчивость к разделению означает, что система продолжает работать, даже если между узлами нарушилась связь. Это базовое требование для распределённой архитектуры, потому что сетевые разделения полностью исключить нельзя.
Разделение сети возникает, когда одна часть кластера перестаёт обмениваться данными с другой. Узлы при этом могут оставаться живыми, принимать запросы и считать, что всё в порядке, но общей картины уже нет.
Если система не умеет жить в таких условиях, она плохо подходит для реального распределённого развёртывания. Поэтому на практике свойство P обычно не выбирают как опцию — его приходится учитывать как данность.
Почему нельзя получить все три свойства сразу
Потому что при сетевом разделении система сталкивается с конфликтом: либо отдавать только проверенно согласованные данные, либо продолжать отвечать на запросы несмотря на разрыв связи. Одновременно гарантировать и то и другое для всех узлов нельзя.
Допустим, кластер разделился на две части. В одной части запись уже произошла, в другой о ней ещё не знают. Если вторая часть продолжит отвечать клиентам, она может вернуть устаревшее значение. Это сохраняет доступность, но ломает согласованность.
Есть и обратный путь. Узлы могут отказаться обслуживать часть запросов, пока не восстановят связь и не убедятся, что данные едины. Тогда согласованность сохраняется, но доступность падает.
Именно в этом и состоит практический смысл теоремы CAP.
Какие комбинации CAP обсуждают чаще всего
В распределённых базах данных обычно говорят о конфигурациях CP и AP. Теоретически существует и вариант CA, но для систем, где возможны сетевые разделения, он почти неприменим.
| Тип | Что сохраняется | Чем жертвуют | Как ведёт себя система |
| CP | Согласованность и устойчивость к разделению | Доступность | При разделении часть узлов может перестать принимать запросы, чтобы не отдавать противоречивые данные |
| AP | Доступность и устойчивость к разделению | Строгая согласованность | Узлы продолжают отвечать, но часть ответов может временно отражать старую версию данных |
| CA | Согласованность и доступность | Устойчивость к разделению | Работает только пока между узлами нет сетевого разрыва |
С конфигурацией CA есть важная оговорка. Если система действительно распределена, возможность разделения сети нельзя отбросить. Поэтому CA удобно обсуждать как модель без сетевых сбоев, но не как полноценный выбор для распределённого кластера.
Что означает CP-подход
CP-система сохраняет единое состояние данных даже во время сетевого разделения, но ради этого может временно перестать обслуживать часть запросов. Приоритет здесь у корректности данных.
Если один сегмент сети не может подтвердить актуальность записи, он лучше откажет клиенту или замрёт до восстановления связи. Такое поведение полезно там, где расхождение данных недопустимо.
Обычно этот вариант выбирают для операций, связанных с деньгами, остатками, заказами, правами доступа и другими чувствительными записями. Ошибка из-за устаревших данных в таких сценариях обходится дороже, чем короткая недоступность.
Что означает AP-подход
AP-система старается отвечать на запросы даже во время разделения сети, принимая риск временной несогласованности данных. После восстановления связи различия между узлами приводят к единому состоянию.
Это часто называют eventual consistency — согласованностью в итоге. Смысл в том, что копии данных могут на время расходиться, но система затем синхронизирует их.
Такой подход подходит для нагрузочных распределённых сервисов, где постоянная доступность важнее немедленной строгости. Например, для сбора событий, некоторых типов каталогов, лент активности или геораспределённых приложений.
Существует ли CA в реальной распределённой системе
Полноценная CA-система в условиях реального сетевого разделения невозможна, потому что ей пришлось бы игнорировать сам факт разрыва связи между узлами. Поэтому в распределённой архитектуре вариант CA обычно рассматривают как теоретическую модель или как поведение системы до первого разделения.
При этом базы данных с сильной согласованностью и высокой доступностью существуют. Например, реляционная СУБД может обеспечивать оба свойства в пределах одного узла или в сценариях репликации, пока нет критического сетевого разрыва между компонентами.
Из-за этого вокруг CA часто возникает путаница. Люди видят доступную и согласованную базу и делают вывод, что CAP опровергнут. Но теорема говорит именно о поведении при разделении сети, а не в спокойном режиме.
Как NoSQL-базы связаны с теоремой CAP
NoSQL-базы часто обсуждают через CAP, потому что они изначально создавались с расчётом на горизонтальное масштабирование и работу на множестве узлов. Для таких систем выбор между строгой согласованностью и постоянной доступностью особенно заметен.
В отличие от классических реляционных систем, которые долгое время чаще масштабировались вертикально, многие NoSQL-решения строятся вокруг распределённой модели с самого начала. Поэтому свойства CAP у них не теоретическая надстройка, а часть архитектуры.
При этом нельзя сводить выбор базы только к ярлыку CP или AP. Реальные СУБД дают настройки репликации, уровней чтения и записи, режимов согласования. Но базовый архитектурный уклон всё равно остаётся.
Как MongoDB соотносится с CAP
MongoDB обычно относят к системам CP: при проблемах со связью она стремится сохранить согласованность, даже если часть операций временно станет недоступной. Это связано с устройством набора реплик и ролью основного узла.
В типичной конфигурации записи принимает один primary-узел, а остальные secondary-узлы копируют журнал операций и обновляют свои данные. Чтение по умолчанию тоже идёт с primary, хотя режимы чтения можно настраивать.
Если основной узел пропадает, один из вторичных узлов с актуальным состоянием может стать новым primary. Пока идёт выбор нового основного узла и остальные реплики догоняют его состояние, часть операций записи недоступна. Зато система избегает противоречивых записей в разных частях кластера.
Как Cassandra соотносится с CAP
Apache Cassandra обычно относят к системам AP: она сохраняет доступность и устойчивость к разделению, допуская временное расхождение данных. Её архитектура без единого ведущего узла как раз поддерживает такой выбор.
В Cassandra нет одного master-узла, через который проходят все записи. Узлы равноправны, поэтому клиент может обращаться к разным точкам кластера.
При сетевом разделении это помогает не останавливать обработку запросов. Но одна часть системы может на время знать о данных меньше, чем другая. Затем различия устраняются механизмами синхронизации и восстановления состояния между узлами.
Такой подход удобен там, где важен непрерывный приём данных и высокая доступность распределённого сервиса.
Как CAP влияет на выбор базы данных для микросервисов
Теорема CAP помогает подобрать хранилище под требования конкретного сервиса. Если сервису критична строгая корректность данных, чаще выбирают системы с уклоном в CP; если важнее постоянный ответ и работа при разрывах сети, смотрят в сторону AP.
Это особенно заметно в микросервисной архитектуре. Каждый сервис может иметь собственную базу, собственную модель данных и собственные требования к чтению и записи.
У платёжного сервиса одни приоритеты. У сервиса аналитики или событий — другие.
Поэтому в одной системе нередко сосуществуют разные хранилища. Реляционная база может отвечать за транзакционно чувствительные данные, а распределённая NoSQL-база — за потоки событий, кэш или быстро растущие коллекции записей.
Как применять теорему CAP на практике
На практике CAP используют не как формулу выбора одной базы на все случаи, а как рамку для принятия архитектурных решений. Сначала определяют, что произойдёт с приложением при устаревших данных, отказе в записи и сетевом разделении, а затем выбирают допустимый компромисс.
Удобно задавать себе несколько прямых вопросов:
- Можно ли на короткое время вернуть не самую свежую версию данных?
- Допустим ли отказ в записи или чтении во время сбоя связи между узлами?
- Какие операции критичны к расхождению данных, а какие нет?
- Нужно ли приложению работать сразу в нескольких локациях?
- Как быстро система должна восстанавливаться после разделения сети?
Ответы на эти вопросы обычно быстро показывают реальный приоритет. Не абстрактный, а тот, который диктует логика продукта.
Частые заблуждения о теореме CAP
Главное заблуждение — считать, что любая распределённая система всегда имеет только два свойства из трёх. Корректнее говорить так: при сетевом разделении приходится выбирать между согласованностью и доступностью, потому что устойчивость к разделению уже обязательна.
Есть и другие частые ошибки:
- CAP не описывает все свойства распределённой системы. Она не заменяет разговор о задержках, пропускной способности, модели транзакций и способах репликации.
- Ярлык CP или AP не раскрывает все детали конкретной СУБД. У многих систем есть настраиваемые режимы чтения и записи.
- Теорема не говорит, что одна группа баз данных лучше другой. Она лишь показывает цену выбора.
Если помнить об этих ограничениях, CAP остаётся полезным инструментом, а не источником путаницы.
Коротко: что нужно запомнить о CAP
Теорема CAP объясняет поведение распределённых систем при сетевом разделении. В такой момент нельзя одновременно сохранить строгую согласованность данных и полную доступность всех узлов.
CP-подход выбирают там, где данные должны оставаться едиными любой ценой. AP-подход подходит там, где система должна продолжать отвечать даже при временных расхождениях. Устойчивость к разделению для распределённой архитектуры — не бонус, а исходное условие.