Ответ
CAP-теорема (теорема Брюера) — это фундаментальный принцип, утверждающий, что в распределенной системе, подверженной сетевым разделениям (Partition, P), невозможно одновременно обеспечить все три свойства:
- Согласованность (Consistency, C): Все узлы видят одни и те же данные в один и тот же момент времени. Каждое чтение возвращает самую последнюю запись или ошибку.
- Доступность (Availability, A): Каждый запрос (чтение или запись) к работоспособному узлу получает не-ошибочный ответ в разумные сроки, без гарантии, что это самые свежие данные.
- Устойчивость к разделению (Partition tolerance, P): Система продолжает функционировать, несмотря на произвольный обрыв связи (потерю сообщений) между узлами.
Ключевой вывод: При возникновении сетевого раздела (P) система может гарантировать либо Согласованность (C), либо Доступность (A), но не оба свойства сразу.
Практические следствия и примеры систем:
| Выбор при разделении | Характеристика | Примеры систем |
|---|---|---|
| CP (Consistency + Partition Tolerance) | Жертвует доступностью. При разделении не отвечающие узлы блокируют запись/чтение до восстановления согласованности. | HBase, MongoDB (с настройками strong consistency), ZooKeeper, традиционные RDBMS в кластере. |
| AP (Availability + Partition Tolerance) | Жертвует согласованностью. Система остается доступной для чтения и записи, но данные на разных узлах могут временно расходиться (eventual consistency). | Cassandra, DynamoDB, CouchDB, Riak. |
| CA (Consistency + Availability) | Теоретически невозможна в распределенной системе. Реализуется только в системах без разделений (например, одиночный узел БД). | Неприменимо к распределенным системам. |
Пример AP-подхода (Cassandra):
// Запись в Cassandra (записывается на узел-координатор и реплики)
session.execute("INSERT INTO users (id, name) VALUES ('user1', 'Alice')");
// Немедленное чтение может вернуть устаревшие данные,
// если реплика, с которой идет чтение, еще не получила обновление.
// Это плата за доступность при разделении.
ResultSet rs = session.execute("SELECT name FROM users WHERE id = 'user1'");
Важно: CAP описывает крайние случаи. На практике многие системы допускают тонкую настройку (например, уровни согласованности в Cassandra) и стремятся к балансу, часто выбирая базовую доступность и итоговую согласованность (BASE) вместо строгой ACID.