Согласованность данных
Согласованность данных (англ. data consistency) — это свойство информационной системы, при котором данные в любой момент времени удовлетворяют заданным логическим, структурным и семантическим правилам, а также не содержат противоречий между своими копиями, хранящимися в разных местах или полученными в результате различных операций. Согласованность является одним из ключевых требований к качеству данных и фундаментальным принципом теории баз данных, систем управления базами данных (СУБД) и распределённых систем.
История возникновения понятия
Понятие согласованности данных возникло в контексте развития реляционных баз данных в 1970-х годах. Эдгар Кодд, создатель реляционной модели данных, в своих работах определил целостность данных как одно из центральных свойств. В 1983 году Андреас Ройтер и Тео Хердер ввели акроним ACID (Atomicity, Consistency, Isolation, Durability — атомарность, согласованность, изоляция, долговечность), где «C» (Consistency) как раз обозначает требование согласованности транзакций. С развитием распределённых систем и NoSQL-баз данных в 2000-х годах появилась теорема CAP (Брюэр, 2000), которая показала, что в распределённой системе невозможно одновременно обеспечить согласованность, доступность и устойчивость к разделению сети. Это привело к появлению более слабых моделей согласованности, таких как «eventual consistency» (согласованность в конечном счёте).
Виды согласованности данных
По отношению к транзакциям (ACID-согласованность)
В рамках ACID-модели согласованность означает, что каждая транзакция переводит базу данных из одного согласованного состояния в другое согласованное состояние. Все ограничения целостности (первичные ключи, внешние ключи, уникальные индексы, проверочные ограничения) должны быть соблюдены до и после выполнения транзакции. Если транзакция нарушает какое-либо правило, она откатывается целиком.
По времени и пространству (сильная и слабая согласованность)
- Сильная согласованность (strong consistency): после завершения операции записи любое последующее чтение немедленно возвращает записанное значение. Требует синхронизации всех реплик данных. Характерна для классических реляционных СУБД (PostgreSQL, Oracle, MySQL в режиме InnoDB).
- Слабая согласованность (weak consistency): чтение может вернуть устаревшие данные, если запись ещё не распространилась на все реплики. Используется в системах, где доступность важнее актуальности, например, в кэшах (Redis, Memcached).
- Согласованность в конечном счёте (eventual consistency): если в систему не поступают новые записи, то через некоторое время все реплики придут к единому состоянию. Это самая распространённая модель в распределённых NoSQL-системах (Cassandra, Amazon DynamoDB, Riak).
- Каузальная согласованность (causal consistency): гарантирует, что операции, связанные причинно-следственной связью, будут видны всем узлам в правильном порядке. Операции, не связанные между собой, могут наблюдаться в разном порядке.
По логике приложения
- Семантическая согласованность: данные соответствуют бизнес-правилам предметной области. Например, сумма дебетов и кредитов в бухгалтерской системе должна быть равна нулю.
- Структурная согласованность: данные соответствуют схеме (структуре) базы данных — типам полей, ограничениям, связям между таблицами.
Проблемы нарушения согласованности
Конфликты параллельных транзакций
При одновременном доступе нескольких пользователей или процессов к одним и тем же данным могут возникать аномалии:
- Грязное чтение (dirty read): чтение данных, записанных незавершённой транзакцией.
- Неповторяющееся чтение (non-repeatable read): повторное чтение в рамках одной транзакции даёт разные результаты из-за изменений, внесённых другими транзакциями.
- Фантомное чтение (phantom read): при повторном выполнении запроса появляются новые строки, добавленные другой транзакцией.
- Потерянное обновление (lost update): две транзакции одновременно читают и модифицируют одни и те же данные, перезаписывая изменения друг друга.
Проблемы распределённых систем
В распределённых системах к перечисленным аномалиям добавляются:
- Расхождение реплик (split-brain): из-за разрыва сети разные части системы начинают независимо обрабатывать записи, после восстановления связи данные невозможно объединить без потерь.
- Задержка распространения (propagation delay): данные, записанные на один узел, не сразу становятся доступными на других узлах.
Методы обеспечения согласованности
На уровне СУБД
- Транзакции с ACID-гарантиями: использование механизмов блокировок (пессимистическая блокировка) или версионирования строк (MVCC, Multi-Version Concurrency Control) для изоляции транзакций.
- Ограничения целостности (constraints): первичные ключи, внешние ключи, уникальные ограничения, проверки (CHECK), триггеры.
- Журналирование (write-ahead logging, WAL): запись изменений в журнал до применения к основной структуре данных, что позволяет восстановить согласованное состояние после сбоя.
В распределённых системах
- Протоколы консенсуса: Paxos, Raft, Zab — используются для достижения согласия между узлами о порядке операций.
- Двухфазный коммит (2PC, Two-Phase Commit): координатор опрашивает все участники, готовы ли они зафиксировать транзакцию, и только после единогласного ответа фиксирует её.
- Кворумные протоколы: для чтения и записи требуется согласие определённого числа узлов (например, запись на N узлов, чтение с M узлов, при N + M > общего числа узлов).
- Синхронная и асинхронная репликация: при синхронной репликации запись считается успешной только после подтверждения от всех реплик; при асинхронной — после записи на один узел.
На уровне приложения
- Оптимистичная блокировка (optimistic locking): приложение проверяет версию данных перед записью; если версия изменилась, операция повторяется.
- Пессимистичная блокировка (pessimistic locking): приложение блокирует строку или таблицу на время своей работы.
- Событийно-ориентированная архитектура (Event Sourcing): вместо хранения текущего состояния система хранит последовательность событий, из которых текущее состояние может быть восстановлено в любой момент.
- Сага (Saga): последовательность локальных транзакций, каждая из которых имеет компенсирующее действие на случай отката.
Согласованность в различных типах систем
Реляционные базы данных
Реляционные СУБД (PostgreSQL, MySQL, Oracle, Microsoft SQL Server) традиционно обеспечивают сильную согласованность в рамках одной транзакции. Они поддерживают уровни изоляции транзакций (Read Uncommitted, Read Committed, Repeatable Read, Serializable), которые определяют, какие аномалии допускаются. Наиболее строгий уровень — Serializable — гарантирует полную согласованность, но снижает производительность.
NoSQL-базы данных
NoSQL-системы (MongoDB, Cassandra, Couchbase, Redis) часто жертвуют сильной согласованностью в пользу доступности и производительности. Они предлагают настраиваемые модели согласованности: например, Cassandra позволяет указать уровень согласованности для каждой операции (ONE, QUORUM, ALL). MongoDB поддерживает сильную согласованность в рамках одной реплики, но в распределённой конфигурации может переключаться на eventual consistency.
Распределённые системы общего назначения
- Системы управления конфигурациями (ZooKeeper, etcd): обеспечивают строгую линейную согласованность (linearizability) за счёт протокола консенсуса Raft. Используются для хранения критичных метаданных (координация сервисов, распределённые блокировки).
- Кэширующие системы (Redis, Memcached): обычно работают в режиме слабой согласованности, так как кэш может быть инвалидирован или обновлён с задержкой.
- Брокеры сообщений (Kafka, RabbitMQ): согласованность зависит от настроек репликации и подтверждений (acks). Kafka с acks=all и минимальным числом реплик (min.insync.replicas) обеспечивает строгую согласованность.
Критика и ограничения
Обеспечение сильной согласованности в распределённых системах сопряжено со значительными издержками: снижением доступности, увеличением задержек, необходимостью синхронизации узлов. Теорема CAP показывает, что в случае разрыва сети (partition) система может выбрать либо согласованность, либо доступность, но не оба свойства одновременно. Это привело к распространению компромиссных моделей (BASE — Basically Available, Soft state, Eventual consistency), которые отказываются от строгой согласованности в пользу высокой доступности.
Кроме того, в некоторых приложениях (например, социальные сети, рекомендательные системы) строгая согласованность не требуется: пользователь может не заметить задержки в несколько секунд при обновлении ленты новостей. В таких случаях eventual consistency является экономически оправданным выбором.
Интересные факты
- Термин «согласованность в конечном счёте» (eventual consistency) популяризировали Вернер Фогельс (Amazon) и Дэн Притчетт (IBM) в 2007–2008 годах.
- В системе Google Spanner используется глобальная синхронизация времени (TrueTime API) для обеспечения внешней согласованности (external consistency) — сильнейшей формы согласованности, эквивалентной последовательной согласованности в глобальном масштабе.
- Некоторые СУБД (например, CockroachDB) реализуют «сериализуемую изоляцию снимков» (SSI, Serializable Snapshot Isolation), которая сочетает производительность MVCC с гарантиями сериализуемости.
Источники
- Codd, E. F. (1970). «A Relational Model of Data for Large Shared Data Banks». Communications of the ACM.
- Gray, J., Reuter, A. (1993). «Transaction Processing: Concepts and Techniques». Morgan Kaufmann.
- Brewer, E. (2000). «Towards Robust Distributed Systems» (keynote at PODC).
- Vogels, W. (2009). «Eventually Consistent». Communications of the ACM.
- Kleppmann, M. (2017). «Designing Data-Intensive Applications». O'Reilly Media.
- Bernstein, P. A., Newcomer, E. (2009). «Principles of Transaction Processing». Morgan Kaufmann.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →