Коротко: CAP-теорема: распределённая система не гарантирует все три свойства сразу; поскольку сеть рвётся, выбор на практике — между C и A в момент сбоя.

Коротко: CAP-теорема говорит, что распределённая система не может одновременно гарантировать все три свойства — согласованность (Consistency), доступность (Availability) и устойчивость к разделению сети (Partition tolerance). Поскольку сеть рано или поздно «рвётся», на практике выбор стоит между C и A в момент сбоя. Разберём, что это значит и как влияет на выбор хранилища.

Что означают C, A, P

  • C — Consistency (согласованность). Любое чтение возвращает самые свежие данные: все узлы видят одно и то же. (Это не та consistency, что в ACID — здесь про согласованность реплик.)
  • A — Availability (доступность). Любой запрос получает ответ (не ошибку), даже если часть узлов недоступна.
  • P — Partition tolerance (устойчивость к разделению). Система продолжает работать, когда сеть между узлами разорвана и они не видят друг друга.

Почему нельзя получить все три

В распределённой системе сетевые разделения неизбежны (пакеты теряются, узлы отваливаются). Значит P — не опция, а данность. Остаётся выбор в момент разделения:

  • CP: жертвуем доступностью ради согласованности — узел, который не уверен в свежести данных, лучше вернёт ошибку/подождёт, чем отдаст устаревшее.
  • AP: жертвуем строгой согласованностью ради доступности — отвечаем всегда, но возможно слегка устаревшими данными (eventual consistency).

Важный нюанс: выбор C vs A проявляется только во время разделения сети. Когда всё работает нормально, система может давать и то, и другое.

Примеры систем

  • CP: классические RDBMS в синхронной репликации, etcd/ZooKeeper, MongoDB (по умолчанию), HBase. Лучше «недоступно», чем «неверно».
  • AP: Cassandra, DynamoDB, Riak. Лучше «доступно с возможной задержкой согласования», чем «отказ».

Многие современные хранилища настраиваемы: уровень согласованности задаётся на уровне запроса (например, кворумные чтения/записи в Cassandra).

Как это влияет на ваш выбор

Вопрос не «какая база лучше», а «что критичнее для конкретных данных»:

  • Деньги, остатки, бронирование — обычно нужна строгая согласованность (CP-подход): лучше отказать, чем продать один билет дважды.
  • Лента, лайки, аналитика, кэш — переживут небольшую рассинхронизацию ради доступности (AP): пусть счётчик лайков обновится через секунду.

PACELC — более честное расширение

CAP описывает только поведение при разделении. Теорема PACELC добавляет: «а если разделения нет (Else), то выбор между Latency и Consistency». То есть даже в норме за строгую согласованность платят задержкой (нужны подтверждения от реплик). Это ближе к реальным компромиссам.

Практический вывод

Не ищите систему «без компромиссов» — её нет. Определите для каждого типа данных, что важнее в момент сбоя: не отдать устаревшее (C) или всегда ответить (A). Часто в одном продукте сосуществуют оба подхода: критичные данные в CP-хранилище, второстепенные — в AP.

Если выбираете хранилище под высоконагруженный продукт и взвешиваете эти компромиссы — разберём под вашу задачу на консультации.