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

Что такое согласованность?

2.0 Middle🔥 201 комментариев
#DevOps и инфраструктура#Django

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

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

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

Согласованность (Consistency)

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

1. ACID: согласованность как целостность данных

В контексте ACID трансакций, согласованность (Consistency) означает, что база данных переходит из одного согласованного состояния в другое согласованное состояние.

Согласованное состояние:                Несогласованное состояние:
Сумма счётов = $1000                   Счёт А: -$100
Счёт А: $500                           Счёт Б: $1100
Счёт Б: $500                           (сумма изменилась!)
        ↓ трансакция                            ↓ ошибка трансакции
Счёт А: $400        ← согласованное  Откат к согласованному состоянию
Счёт Б: $600        ← состояние      Счёт А: $500
Сумма: $1000                          Счёт Б: $500

Пример на Python с SQLAlchemy:

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker, declarative_base
from sqlalchemy.exc import IntegrityError

Base = declarative_base()

class Account(Base):
    __tablename__ = 'accounts'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    balance = Column(Integer)
    
    def __repr__(self):
        return f"Account(id={self.id}, balance={self.balance})"

engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)

# Создаём счёта
session = Session()
account_a = Account(id=1, name="Alice", balance=500)
account_b = Account(id=2, name="Bob", balance=500)
session.add_all([account_a, account_b])
session.commit()

# Согласованная трансакция (перевод денег)
try:
    account_a.balance -= 100  # Снимаем со счёта А
    account_b.balance += 100  # Добавляем на счёт Б
    session.commit()  # Обе операции выполняются вместе
    print(f"Трансакция успешна: {account_a.balance}, {account_b.balance}")
except IntegrityError as e:
    session.rollback()  # Откатываем обе операции
    print(f"Ошибка: {e}")

2. CAP: согласованность в распределённых системах

Теорема CAP утверждает, что невозможно одновременно достичь:

C (Consistency)     — все узлы видят одинаковые данные
A (Availability)    — система всегда доступна
P (Partition)       — система работает при разделении сети

Подходимся выбрать только 2 из 3!

CP системы (Consistency + Partition tolerance)

Жертвуют доступностью. Если сеть разделилась, система может быть недоступна.

# Пример: консервативный подход
# При разделении сети блокируем запросы, пока не восстановимся

if network_partition_detected():
    raise ServiceUnavailable("Cannot guarantee consistency")
else:
    serve_request()  # Гарантируем согласованность

Примеры: PostgreSQL, MongoDB, Google Spanner

AP системы (Availability + Partition tolerance)

Жертвуют консеквентностью. При разделении сети узлы продолжают работать независимо, может быть временная несогласованность.

# Пример: оптимистичный подход
# При разделении сети каждый узел работает самостоятельно

if network_partition_detected():
    # Работаем локально, данные могут расходиться
    write_locally(data)
    schedule_sync_later()  # Синхронизируем когда сеть восстановится
else:
    write_consistently(data)

Примеры: DynamoDB, Cassandra, Riak

3. Уровни согласованности (Consistency Models)

Strong Consistency (Строгая согласованность)

Все прочитанные данные — это самые последние версии.

# Строгая согласованность
write(key='user_123', value={'name': 'Alice', 'age': 25})
data = read(key='user_123')  # Получим свежие данные
assert data['age'] == 25  # Гарантирует!

Проблема: может быть медленно при распределённой системе (нужна синхронизация).

Eventual Consistency (Итоговая согласованность)

Данные в конечном итоге станут согласованными, но могут быть задержки.

# Итоговая согласованность (как в NoSQL, кэшах)
write(key='counter', value=10)  # Пишем на узел А
data = read(key='counter')      # Читаем с узла Б
# Может вернуть 9 или 10 (задержка синхронизации)
# Но через несколько миллисекунд все узлы будут иметь 10

Преимущества: высокая доступность, производительность

Causal Consistency (Причинная согласованность)

Уважает причинно-следственные отношения между операциями.

# Процесс 1
write(post_id=1, content="Hello")  # Запись

# Процесс 2 (после того как узнал о записи)
comment = read(post_id=1)  # Гарантированно видит "Hello"
write(comment_id=2, text="Nice!")  # Комментарий ко ВСЕМ видимым постам

# Процесс 3
post = read(post_id=1)     # Видит "Hello"
comments = read()          # Видит комментарий "Nice!"

Read-Your-Writes Consistency

Процесс видит свои собственные записи сразу.

user_id = 123
update_user_email(user_id, "new@example.com")  # Пишу
email = get_user_email(user_id)                # Читаю
assert email == "new@example.com"               # Гарантировано!

4. Согласованность в WebSocket / Real-time системах

В real-time приложениях (чаты, сотрудничество) согласованность — это синхронизация состояния между клиентами.

# Последовательно-согласованное редактирование
# (как в Google Docs)

class Document:
    def __init__(self):
        self.version = 0
        self.content = ""
        self.operations = []  # История операций для воспроизведения
    
    def apply_operation(self, op: dict, version: int):
        """Применяет операцию и синхронизирует версию."""
        if version != self.version:
            # Трансформируем операцию для текущей версии
            op = transform(op, self.version - version)
        
        self.content += op['text']
        self.version += 1
        self.operations.append(op)
        
        # Отправляем всем клиентам
        broadcast({
            'version': self.version,
            'operation': op
        })

# Клиент 1: пишет "Hello"
doc.apply_operation({'text': 'Hello'}, version=0)

# Клиент 2: видит то же состояние
assert doc.content == "Hello"

5. Сравнение систем

База данныхМодельПреимуществаНедостатки
PostgreSQLStrongНадёжность, ACIDМедленнее на масштабе
MongoDBStrong (по умолчанию)Гибкость, ACIDСложнее масштабировать
DynamoDBEventualМасштабируемость, производительностьМожет быть задержка, нужен careful design
CassandraEventualРаспределённость, надёжностьСложнее для strong consistency
RedisStrong (单thread)Скорость (в памяти)Может теряться данные, ограниченный объём

6. Проблемы несогласованности

Race Condition

Два процесса конкурируют за один ресурс:

# Несогласованно:
balance = 100

# Процесс 1                 # Процесс 2
temp = balance  # 100       temp = balance  # 100
temp -= 10      # 90        temp += 20      # 120
balance = temp  # 90        balance = temp  # 120

# Результат: 120 (потеряли операцию Процесса 1!)

Решение: synchronization (блокировки, atomics)

import threading

lock = threading.Lock()
balance = 100

def withdraw():
    global balance
    with lock:  # Критическая секция
        temp = balance
        temp -= 10
        balance = temp  # Процесс 2 подождёт!

Dirty Read

Чтение незафиксированных данных:

# Трансакция А: начало
write(user_age, 25)
# Трансакция Б: грязное чтение!
age = read(user_age)  # Видит 25
# Трансакция А: откат (ошибка)
reset(user_age, 20)  # Откатилась, но Б уже видел 25!

Решение: isolation level READ_COMMITTED

Практические рекомендации

  • Для критичных данных — используй Strong Consistency (PostgreSQL, MongoDB с writeConcern)
  • Для высоконагруженных систем — Eventual Consistency (Cassandra, DynamoDB) с careful design
  • Для real-time — Causal Consistency (CRDT, Event Sourcing)
  • Профилируй! — найди баланс между надёжностью и производительностью

Согласованность — это баланс между надёжностью и производительностью в распределённых системах.

Что такое согласованность? | PrepBro