← Назад к вопросам

Что такое CP система?

3.0 Senior🔥 91 комментариев
#Базы данных и SQL#Кэширование и NoSQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

CP система (CAP теорема)

Определение

CP система (Consistency + Partition tolerance) — это система, которая, согласно теореме CAP, может гарантировать только две из трёх характеристик: Consistency, Availability и Partition tolerance.

CAP теорема (Brewer's theorem) утверждает, что распределённая система может одновременно обеспечить максимум ДВЕ из этих трёх свойств:

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

Три типа систем

1. CA система — Consistency + Availability (но НЕ отказоустойчива при разделении)

  • Пример: традиционная СУБД (PostgreSQL с одним мастером)
  • Проблема: при разрыве сети система неработоспособна

2. CP система — Consistency + Partition tolerance (но НЕ всегда доступна)

  • Пример: Google BigTable, MongoDB, HBase
  • Поведение: при разделении сети система блокирует запросы для обеспечения консистентности

3. AP система — Availability + Partition tolerance (но НЕ гарантирует консистентность)

  • Пример: Amazon DynamoDB, Cassandra, Riak
  • Поведение: при разделении сети система продолжает работать, но данные могут быть несогласованными (eventual consistency)

CP система подробно

CP система выбирает консистентность над доступностью.

При разделении сети (partition):

  • Система продолжает работать (partition tolerance ✓)
  • Система гарантирует, что все клиенты видят одни и те же данные (consistency ✓)
  • Но система может стать недоступной для части клиентов (availability ✗)

Пример CP системы: MongoDB

// CP система: MongoDB с репликацией
// При разделении сети одна часть реплик станет недоступной
// но оставшаяся часть будет обслуживать запросы и гарантировать консистентность

public class MongoDBExample {
    public void demonstrateConsistency(MongoClient mongoClient) {
        MongoDatabase database = mongoClient.getDatabase("myapp");
        MongoCollection<Document> collection = database.getCollection("users");
        
        // Вставляем документ
        Document user = new Document()
            .append("_id", new ObjectId())
            .append("name", "Alice")
            .append("balance", 1000);
        collection.insertOne(user);
        
        // При разделении сети:
        // Если этот узел — часть большинства реплик — запросы работают
        // Если этот узел — часть меньшинства — запросы блокируются
        // Но когда сеть восстанавливается — все узлы имеют консистентные данные
    }
}

Пример CP системы: HBase

public class HBaseExample {
    public void putDataHBase(Table table) throws IOException {
        // HBase использует HDFS и ZooKeeper
        // ZooKeeper гарантирует консистентность между узлами
        
        Put put = new Put(Bytes.toBytes("user123"));
        put.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("name"), Bytes.toBytes("Alice"));
        table.put(put);
        
        // При разделении сети:
        // ZooKeeper выбирает лидера (quorum consensus)
        // Клиенты могут работать только с лидером
        // Это гарантирует консистентность, но жертвует доступностью
    }
}

Сравнение стратегий

ХарактеристикаCACPAP
Консистентность
Доступность
Отказоустойчивость
ПримерPostgreSQLMongoDBCassandra
СценарийОдин дата-центрФинансовые системыВысоконагруженные системы

Когда использовать CP систему

Выбирайте CP когда:

  • Критична консистентность: финансовые системы, банки, e-commerce
  • Ошибки неприемлемы: медицинские системы, системы управления
  • Количество данных позволяет: можете хранить всё в памяти одного узла
  • Сеть надёжна: частые разделения сети нежелательны

Практический пример в Java

// CP система при банковском переводе
public class BankTransferService {
    private MongoTemplate mongoTemplate;
    
    public void transfer(String fromAccountId, String toAccountId, BigDecimal amount) {
        // Используем транзакции MongoDB для ACID гарантий
        mongoTemplate.inTransaction()
            .execute(session -> {
                // Вычитаем из первого счёта
                UpdateResult result1 = mongoTemplate
                    .updateFirst(
                        Query.query(Criteria.where("_id").is(fromAccountId)),
                        Update.update("balance", "-" + amount),
                        Account.class
                    );
                
                // Добавляем на второй счёт
                UpdateResult result2 = mongoTemplate
                    .updateFirst(
                        Query.query(Criteria.where("_id").is(toAccountId)),
                        Update.update("balance", "+" + amount),
                        Account.class
                    );
                
                // Если оба успешны — фиксируем
                // Если одно не удалось — откатываем (ACID гарантия)
                return result1.getModifiedCount() > 0 && result2.getModifiedCount() > 0;
            });
    }
}

Важные выводы

  1. CAP теорема — необходимое зло — вы НЕ можете иметь всё три свойства одновременно
  2. Выбирайте осознанно — на основе требований вашей системы
  3. Это не черное и белое — есть компромиссы в спектре (eventual consistency в CP системах)
  4. Масштабирование требует жертв — начните с CA, затем решайте нужна ли CP или AP архитектура