Открыть сервис

Уровни согласованности

Уровни согласованности (англ. consistency levels) — это параметры, определяющие, насколько строго система распределённых данных (например, база данных, кэш, реплицированное хранилище) гарантирует актуальность и единообразие информации для всех узлов и клиентов в любой момент времени. В распределённых системах, где данные хранятся на нескольких серверах (репликах), невозможно одновременно обеспечить и мгновенную синхронизацию, и высокую доступность, и устойчивость к сетевым разделениям (согласно теореме CAP). Уровни согласованности представляют собой компромиссные модели, которые позволяют разработчику выбирать между строгой актуальностью данных (сильная согласованность) и низкими задержками / высокой доступностью (слабая согласованность).

История и теоретическая основа

Понятие уровней согласованности возникло в 1970–1980-х годах с развитием распределённых баз данных и систем управления транзакциями. Классическая модель ACID (атомарность, согласованность, изоляция, долговечность) предполагала строгую согласованность: после завершения транзакции все последующие чтения видят её результат. Однако с ростом интернет-сервисов (конец 1990-х — 2000-е) стало ясно, что для масштабируемости и отказоустойчивости необходимо ослабить требования к согласованности.

В 2000 году Эрик Брюер сформулировал теорему CAP (C — согласованность, A — доступность, P — устойчивость к разделению), согласно которой в распределённой системе можно одновременно обеспечить только два из трёх свойств. Это привело к появлению моделей BASE (Basically Available, Soft state, Eventually consistent — «базовая доступность, мягкое состояние, конечная согласованность»), где согласованность приносится в жертву доступности. Впоследствии были разработаны формальные уровни согласованности, позволяющие гибко настраивать поведение системы.

Классификация уровней согласованности

Существует несколько общепринятых моделей, упорядоченных от наиболее строгих к наименее строгим.

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

После записи данных любое последующее чтение (на любом узле) немедленно возвращает записанное значение. Система ведёт себя как единая копия данных. Реализуется через синхронную репликацию (запись подтверждается только после обновления всех реплик) или через протоколы консенсуса (например, Paxos, Raft). Требует блокировок и увеличивает задержки, особенно при сбоях. Применяется в финансовых системах, банковских транзакциях, каталогах товаров с жёсткими требованиями к актуальности.

Конечная согласованность (Eventual consistency)

Система гарантирует, что при отсутствии новых записей все реплики со временем придут к одному и тому же состоянию. Однако в произвольный момент времени разные клиенты могут видеть разные версии данных. Это самая слабая форма согласованности, характерная для многих NoSQL-баз (например, Cassandra, DynamoDB). Обеспечивает высокую доступность и низкие задержки, но требует от разработчика обработки конфликтов (например, через «последний пишущий побеждает» или векторные часы). Подходит для социальных сетей, лент новостей, систем кэширования.

Каузальная согласованность (Causal consistency)

Гарантирует, что операции, связанные причинно-следственными отношениями (например, запись A предшествует записи B), будут видны всем узлам в правильном порядке. Операции, не связанные причинно, могут наблюдаться в любом порядке. Эта модель сильнее конечной, но слабее строгой. Реализуется с помощью отслеживания зависимостей (векторные часы, графы зависимостей). Используется в системах совместного редактирования документов (Google Docs), многопользовательских играх.

Монотонная согласованность (Monotonic consistency)

Включает несколько подуровней:

  • Монотонное чтение (Monotonic reads): если клиент прочитал определённое значение, то все последующие чтения (от того же клиента) вернут это же или более новое значение. Исключает эффект «отката времени».
  • Монотонная запись (Monotonic writes): операции записи от одного клиента выполняются в порядке их отправки (не переупорядочиваются).
  • Чтение своих записей (Read your writes): клиент, сделавший запись, немедленно видит её результат (даже если другие клиенты ещё не видят).
  • Запись следует за чтением (Writes follow reads): если клиент прочитал значение X, то последующая запись будет видна после X.

Эти модели часто комбинируются и реализуются в базах данных с сессионной согласованностью (например, в Riak, MongoDB с настройками read/write concern).

Сессионная согласованность (Session consistency)

Гарантирует, что в рамках одной клиентской сессии (соединения) данные видны согласованно (например, монотонное чтение + чтение своих записей). За пределами сессии согласованность может быть слабее. Реализуется через привязку запросов к одной реплике (sticky sessions) или через временные метки сессии. Используется в веб-приложениях с аутентификацией и корзинами покупок.

Слабая согласованность (Weak consistency)

Не даёт никаких гарантий: чтение может вернуть любое значение (вплоть до устаревшего или несуществующего). Обычно применяется в системах, где данные не критичны (например, счётчики просмотров, аналитика, логи). Может быть реализована через асинхронную репликацию без подтверждений.

Реализация в популярных системах

Реляционные базы данных (ACID)

Традиционные SQL-системы (PostgreSQL, MySQL, Oracle) по умолчанию обеспечивают строгую согласованность на уровне одной транзакции (через блокировки и изоляцию). Однако при использовании репликации (например, master-slave) возможна конечная согласованность для чтений с реплик (read replicas). В настройках можно задать уровень изоляции транзакций (Read Committed, Repeatable Read, Serializable), что также влияет на согласованность.

NoSQL-базы

  • Apache Cassandra: позволяет настраивать уровень согласованности для каждой операции (запись/чтение). Например, ONE (одна реплика), QUORUM (большинство), ALL (все). Комбинация QUORUM для записи и QUORUM для чтения обеспечивает строгую согласованность, ONE — конечную.
  • Amazon DynamoDB: поддерживает Eventually Consistent (по умолчанию) и Strongly Consistent (дороже, с задержкой). Также есть транзакции с ACID-гарантиями.
  • MongoDB: использует read concern (local, majority, linearizable) и write concern (acknowledged, majority). majority для чтения и записи даёт строгую согласованность.
  • Redis: в кластерном режиме по умолчанию конечная согласованность (асинхронная репликация). Есть опция WAIT для синхронной записи на несколько реплик.

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

  • Google Spanner: глобально распределённая база данных со строгой согласованностью, реализованной через синхронизацию времени (TrueTime API) и протокол Paxos.
  • Apache Kafka: использует конечную согласованность для репликации логов, но гарантирует строгий порядок в пределах одной партиции (с помощью лидера).

Практическое применение и компромиссы

Выбор уровня согласованности — ключевое архитектурное решение. Основные факторы:

  • Требования к актуальности: финансовые транзакции, бронирования, заказы — нужна строгая согласованность.
  • Допустимые задержки: строгая согласованность увеличивает время ответа (особенно в геораспределённых системах).
  • Доступность: при сбоях сети строгая согласованность может привести к отказу в обслуживании (система блокирует запись, пока не синхронизирует все реплики). Слабая согласованность позволяет продолжать работу.
  • Сложность разработки: конечная согласованность требует обработки конфликтов и «мягкого» состояния (soft state), что усложняет код.

На практике часто используется гибридный подход: критичные данные (баланс счёта) обрабатываются со строгой согласованностью, а некритичные (история просмотров) — с конечной. Многие системы позволяют задавать уровень согласованности для каждой операции (per-operation consistency).

Интересные факты

  • Термин «конечная согласованность» популяризировали инженеры Amazon в начале 2000-х при создании DynamoDB.
  • В системах с конечной согласованностью возможны «фантомные» состояния — например, клиент видит запись, затем она исчезает, а позже появляется снова (если конфликт разрешился в пользу другой версии).
  • Протоколы консенсуса (Paxos, Raft) позволяют эмулировать строгую согласованность даже в условиях сетевых разделений, но ценой снижения производительности.
  • Существуют более экзотические модели — например, «согласованность на основе времени» (timeline consistency) или «согласованность с привязкой к пользователю» (user-centric consistency).

Критика и ограничения

  • Строгая согласованность в глобальных системах (с задержками >100 мс) практически недостижима без существенных потерь производительности.
  • Конечная согласованность может приводить к трудноотлавливаемым ошибкам (например, двойное списание средств, если система не обработала конфликт).
  • Модели согласованности часто путают с изоляцией транзакций (ACID), хотя это разные понятия: изоляция касается параллельных транзакций, а согласованность — видимости данных в распределённой среде.
  • Некоторые системы (например, Cassandra) допускают настройку уровня согласованности, но не гарантируют полного соответствия теоретической модели из-за особенностей реализации (например, «чтение-восстановление» может нарушить монотонность).

Источники

  • Brewer, E. A. (2000). «Towards Robust Distributed Systems» (теорема CAP).
  • Vogels, W. (2009). «Eventually Consistent» (Communications of the ACM).
  • Gilbert, S., Lynch, N. (2002). «Brewer’s Conjecture and the Feasibility of Consistent, Available, Partition-Tolerant Web Services».
  • «Dynamo: Amazon’s Highly Available Key-value Store» (2007).
  • «Cassandra: The Definitive Guide» (Eben Hewitt, 2010).
  • «Designing Data-Intensive Applications» (Martin Kleppmann, 2017).
  • Документация MongoDB, Apache Cassandra, Redis, Amazon DynamoDB.

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →