Распределённые системы

Модели согласованности

Цели урока

  • Различать linearizable, sequential, causal и eventual consistency
  • Применять формулу W+R > N для выбора уровней в Cassandra/DynamoDB
  • Объяснять разницу между C в CAP и C в ACID
  • Выбирать модель согласованности под бизнес-требования

Предварительные знания

  • CAP-теорема: понимание trade-off Consistency vs Availability
  • Репликация: leader/follower, multi-leader подходы
  • Базовое понимание vector clocks (для causal consistency)

DynamoDB показывает корзину с 3 товарами пока на другой реплике уже 4 - и это правильное решение для сервиса с 99.999% uptime. Google Spanner хранит финансовые данные с linearizable consistency и атомными часами в каждом датацентре. Одна буква C в CAP - и за ней скрывается пять разных уровней строгости.

  • **Amazon DynamoDB** - eventual по умолчанию, strongly consistent reads за x2 цену: сознательный trade-off доступность vs стоимость
  • **Google Spanner** - единственная промышленная linearizable глобальная БД, атомные часы в каждом регионе
  • **Cassandra** - tunable consistency per request: разные таблицы с разными политиками в одном кластере
  • **Facebook TAO** - causal consistency для социального графа: ответ виден только если виден исходный пост
  • **Redis Cluster** - eventual по умолчанию, WAIT команда для синхронной репликации при необходимости

Werner Vogels и eventually consistent

В 2008 году CTO Amazon Вернер Фогельс опубликовал статью 'Eventually Consistent' в ACM Queue. Он систематизировал модели согласованности из опыта построения DynamoDB и S3. Главная идея: eventual consistency - не слабость системы, а осознанный инженерный выбор ради масштабируемости. Статья изменила отраслевой дискурс: разработчики перестали стесняться eventual consistency и начали выбирать её явно.

Спектр моделей согласованности

**Amazon DynamoDB, 2012. Prime Day. Сотни миллионов запросов в секунду. Корзина покупателя показывает 3 товара - и одновременно на другой реплике хранится 4 товара.** Покупатель ничего не замечает: через секунду обе реплики сходятся. Это не баг - это осознанный выбор модели согласованности ради 99.999% доступности.

**Путаница терминов:** C в CAP - это НЕ C в ACID. CAP-consistency = linearizability (все узлы видят одно). ACID-consistency = бизнес-инварианты (баланс не уходит в минус). Разные концепции, одна буква.

**Consistency model** - контракт между системой и клиентом: что гарантируется при чтении данных после записи. От самой строгой до самой слабой - это не два варианта, а непрерывный спектр.

МодельГарантияЦена
**Linearizable**Операции выглядят мгновенными, real-time порядокКонсенсус, высокий latency
**Sequential**Единый порядок для всех узлов, не обязательно real-timeКоординация, средний latency
**Causal**Причинно-связанные операции упорядоченыVector clocks, без консенсуса
**Read-your-writes**Своя запись видна сразу в рамках сессииSticky sessions или tokens
**Eventual**Все реплики сойдутся когда-нибудьВозможны stale reads, нужен conflict resolution

**Практическое правило:** чем сильнее модель - тем выше latency и ниже доступность при partition. Выбор модели диктует бизнес-требования: финансовые данные требуют linearizable, корзина покупателя переживёт eventual.

Согласованность - это бинарный выбор: либо есть, либо нет

Согласованность - спектр из минимум 5 уровней, каждый с разным trade-off latency/доступность

На практике одна система может использовать разные уровни для разных операций. Cassandra позволяет выбрать consistency level на каждый запрос. DynamoDB предлагает strongly consistent reads как опцию за двойную цену по latency.

Чем отличается C в CAP от C в ACID?

Linearizability: операции как на одном узле

**Google Spanner, 2012. Первая в мире глобально распределённая БД с linearizable consistency.** Транзакция записана в датацентре Айовы - через несколько миллисекунд любой узел в Токио или Лондоне вернёт актуальное значение. Цена: в каждом датацентре стоят атомные часы и GPS-приёмники.

**Linearizability** - самая строгая практичная модель. Каждая операция выглядит мгновенной в какой-то точке между началом и завершением. После этой точки все читатели видят результат.

Как Spanner достигает глобального порядка

**Цена linearizability:** каждый коммит в Spanner ждёт ~7мс пока TrueTime интервал закроется. Пропускная способность - тысячи tx/сек на узел. DynamoDB (eventual) - миллионы. За глобальный порядок платят скоростью.

СистемаМодельКак реализовано
Google SpannerLinearizableTrueTime API (атомные часы + GPS)
etcd / ZooKeeperLinearizableRaft/ZAB консенсус
PostgreSQL (single)LinearizableSingle node = linearizable by definition
CockroachDBSerializableHLC (Hybrid Logical Clocks) + Raft

Client A записал x=1 и получил подтверждение. Client B начал чтение после этого. Что гарантирует linearizability?

Causal и Eventual: когда строгость не нужна

**Facebook, 2009. 300 млн пользователей. Задача: если видишь комментарий к посту - должен видеть и сам пост.** Требует причинной согласованности (causal consistency). Но порядок двух независимых постов от разных людей - неважен. Это и есть идея causal consistency: упорядочивать только то, что причинно связано.

**Causal consistency** - операции, связанные причинно-следственно, видны всем в одном порядке. Независимые (concurrent) операции могут быть в разном порядке на разных узлах.

**Causal consistency достижима без консенсуса** - достаточно vector clocks или causal tokens. Поэтому она популярна в geo-distributed системах: COPS, Cassandra LWT, MongoDB causal consistency.

Eventual consistency: максимальная доступность

**Eventual consistency** - если новых записей нет, все реплики рано или поздно сойдутся к одному состоянию. "Рано или поздно" - это официальное определение: никаких временных гарантий.

Проблема eventualПримерРешение
**Stale read**Записал пост, обновил страницу - пост исчезRead-your-writes гарантия (sticky session)
**Monotonic violation**Прочитал баланс 100, потом 50, потом 100Monotonic reads (sticky session или версии)
**Write conflicts**Две реплики получили разные значения для xLWW (Last Write Wins) или merge функция

**Session guarantees** - промежуточный вариант: внутри сессии одного пользователя даются дополнительные гарантии (read-your-writes, monotonic reads), между сессиями - eventual. Реализуется через sticky sessions или session tokens с version числами.

Eventual consistency = система может вернуть любой мусор

Eventual consistency = реплики гарантированно сходятся, просто без временных рамок

Eventual гарантирует convergence - все реплики придут к одному значению. Это не означает произвольные данные. При отсутствии новых записей система обязана сойтись. Проблемы - в stale reads во время репликации, а не в произвольных данных.

В социальной сети: Bob отвечает на пост Alice. Какая минимальная модель согласованности гарантирует что читатель не увидит ответ без исходного поста?

Tunable consistency: настраивай под задачу

**Cassandra, 2010. Подход: не выбирай модель один раз для всей БД - выбирай на каждый запрос.** Один сервис пишет с QUORUM (строго), читает с ONE (быстро). Другой сервис пишет с ANY (максимальная скорость), читает с QUORUM (строго). Это tunable consistency - главная инновация Cassandra.

Формула: W + R > N

При N репликах, W подтверждениях записи и R репликах для чтения: если W + R > N, то множества записавших и прочитавших пересекаются. Пересечение гарантирует что хотя бы один из R узлов имеет актуальные данные.

СистемаDefault модельTunable опции
PostgreSQL (single)LinearizableНет (single node)
CockroachDBSerializableStale reads опционально
DynamoDBEventualStrongly consistent reads (x2 стоимость)
CassandraEventual (ONE)ANY/ONE/QUORUM/ALL на каждый запрос
MongoDBEventualLinearizable reads опционально
Redis ClusterEventualWAIT N TIMEOUT для sync replication

Практический выбор в e-commerce

Интернет-магазин использует Cassandra. Товарные цены: QUORUM write + QUORUM read (потеря актуальности цены = репутационный ущерб). Счётчик просмотров товара: ONE write + ONE read (небольшая погрешность допустима, скорость важнее). Корзина: ONE write + QUORUM read (быстрая запись, строгое чтение - клиент должен видеть свои изменения). Три разные consistency policies в одной БД для трёх разных бизнес-требований.

**Pitfall tunable consistency:** если приложение смешивает уровни непоследовательно, возникают тонкие баги. QUORUM write + ONE read не гарантирует свежесть: ONE read может попасть на узел который ещё не получил запись. Документируй policy для каждой таблицы.

QUORUM всегда означает большинство (N/2 + 1)

В Cassandra QUORUM = N/2+1, но важна формула W+R > N, а не конкретное слово 'QUORUM'

Можно получить strong consistency без QUORUM: W=1, R=ALL или W=ALL, R=1 тоже дают W+R > N. 'QUORUM' - это просто удобный preset для баланса. Главное - понимать математику пересечения.

Cassandra с N=5 репликами. Выбрано W=3 (write ack), R=2 (read from replicas). Гарантирует ли это strong consistency?

Вопросы для размышления

  • Возьми любую систему которую строишь или используешь. Какие операции в ней требуют linearizable consistency, а какие можно безопасно перевести на eventual? Как формула W+R > N меняет подход к выбору конфигурации?

Связанные уроки

  • ds-02-cap-theorem — CAP theorem is the foundation of consistency tradeoffs
  • dist-09-raft — Raft provides linearisability as a reference implementation
  • ds-10-crdts — CRDTs represent the eventual consistency end of the spectrum
  • dist-07-transactions — Isolation levels in transactions mirror consistency models
  • db-03-acid
Модели согласованности

0

1

Войти