Конечная согласованность
Конечная согласованность (англ. eventual consistency) — это модель согласованности данных, используемая в распределённых вычислительных системах и базах данных, при которой при отсутствии новых изменений все реплики данных со временем приходят к одному и тому же состоянию. В отличие от строгой (сильной) согласованности, где все узлы системы обязаны немедленно отражать каждое изменение, конечная согласованность допускает временное расхождение данных между узлами, гарантируя, что в конечном итоге, после прекращения записи, все копии данных будут синхронизированы.
История и предпосылки
Концепция конечной согласованности возникла как ответ на ограничения классических моделей согласованности, применявшихся в реляционных базах данных (ACID). С ростом масштабов интернет-сервисов и необходимостью обработки огромных объёмов данных на географически распределённых серверах стала очевидной невозможность поддержания строгой согласованности в реальном времени без значительного снижения производительности и доступности.
Термин был введён в обиход в 2000-х годах, в частности, он активно использовался в контексте систем управления базами данных NoSQL (например, Amazon Dynamo, Apache Cassandra, Riak). В 2000 году Эрик Брюэр сформулировал теорему CAP (теорема Брюэра), которая утверждает, что в распределённой системе невозможно одновременно обеспечить согласованность (Consistency), доступность (Availability) и устойчивость к разделению (Partition tolerance). Разработчики распределённых систем, жертвуя строгой согласованностью, выбирали модель конечной согласованности, чтобы обеспечить высокую доступность и отказоустойчивость.
Принцип работы
В системах с конечной согласованностью данные хранятся на нескольких репликах (копиях), расположенных на разных узлах. При записи нового значения оно может быть записано только на один узел (или на кворум узлов), а затем асинхронно распространено на остальные. В этот промежуток времени разные узлы могут содержать разные версии одних и тех же данных. Читающий запрос, обращённый к узлу, который ещё не получил обновление, может получить устаревшие данные.
Гарантия конечной согласованности заключается в том, что если в систему не поступают новые изменения, то через некоторое время (конечное, но неопределённое) все узлы будут содержать идентичные копии данных. Время, необходимое для достижения согласованности, зависит от задержек в сети, нагрузки на систему, числа реплик и механизмов репликации.
Виды и модификации
Различают несколько подвидов конечной согласованности, которые различаются по степени гарантий и поведению системы:
- Каузальная согласованность (Causal consistency): гарантирует, что связанные по времени (причинно-следственные) операции будут видны всем узлам в правильном порядке. Например, если пользователь сначала создал запись, а затем её отредактировал, то ни один узел не покажет отредактированную версию без создания.
- Согласованность «чтение-свои-записи» (Read-your-writes consistency): гарантирует, что после записи данных пользователь, который их записал, всегда увидит эту запись при последующих чтениях (даже если он переключился на другой узел).
- Согласованность «сессионная» (Session consistency): гарантирует, что в рамках одной сессии взаимодействия пользователя с системой (например, одной HTTP-сессии) все операции чтения будут видеть все записи, сделанные в этой сессии.
- Согласованность «монотонное чтение» (Monotonic read consistency): гарантирует, что если пользователь прочитал определённое значение данных, то все последующие чтения (в рамках той же сессии или запроса) не покажут более старую версию этих данных.
- Согласованность «монотонная запись» (Monotonic write consistency): гарантирует, что записи от одного процесса будут распространяться на все узлы в порядке их выполнения.
Применение
Конечная согласованность широко применяется в системах, где доступность и скорость ответа критичнее, чем абсолютная актуальность данных в каждый момент времени. Основные области использования:
- Социальные сети и мессенджеры: ленты новостей, комментарии, статусы пользователей. Допустимо, что комментарий к посту появится у других пользователей не мгновенно, а с задержкой в несколько секунд.
- DNS (Domain Name System): записи DNS кэшируются на множестве серверов по всему миру. Изменение записи (например, IP-адреса сайта) распространяется не мгновенно, а в течение времени жизни кэша (TTL).
- Распределённые базы данных NoSQL: Apache Cassandra, Amazon DynamoDB, Couchbase, Riak. Эти системы оптимизированы для горизонтального масштабирования и высокой доступности, и конечная согласованность является их базовой моделью.
- Системы кэширования: CDN (Content Delivery Network), кэши веб-приложений. Обновление контента на всех узлах CDN может занимать время.
- Репликация баз данных: многие СУБД (например, MySQL, PostgreSQL) поддерживают асинхронную репликацию, при которой ведомые узлы (slaves) могут отставать от ведущего (master) на некоторое время.
Преимущества и недостатки
Преимущества:
- Высокая доступность: система продолжает работать и принимать запросы даже при отказе части узлов, так как не требуется блокировка всех реплик для записи.
- Высокая производительность: операции записи выполняются быстро, так как не требуют синхронизации со всеми репликами.
- Горизонтальная масштабируемость: легко добавлять новые узлы, не нарушая работу системы.
- Устойчивость к разделению сети: при временном разрыве связи между узлами система продолжает функционировать, а после восстановления связи данные синхронизируются.
Недостатки:
- Временная несогласованность: пользователи могут видеть устаревшие или противоречивые данные.
- Сложность разрешения конфликтов: при одновременной записи на разные узлы могут возникнуть конфликты, которые необходимо разрешать (например, по принципу «последняя запись побеждает» или с помощью версионирования).
- Неприменимость для критически важных данных: не подходит для систем, где требуется строгая актуальность (например, банковские транзакции, управление воздушным движением).
Критика и ограничения
Основная критика модели конечной согласованности связана с тем, что она не даёт чётких гарантий времени, через которое данные станут согласованными. Это может привести к сложным и трудно воспроизводимым ошибкам в приложениях. Разработчикам, использующим такие системы, приходится самостоятельно реализовывать механизмы, обеспечивающие нужный уровень согласованности для конкретных бизнес-сценариев, например, использовать кворумные чтения или версионирование данных.
Кроме того, конечная согласованность не подходит для систем, где требуется соблюдение транзакционных свойств ACID (атомарность, согласованность, изоляция, долговечность) в полном объёме. В таких системах предпочтительнее использовать строгую согласованность, даже ценой снижения производительности и доступности.
Источники
- Brewer, E. A. (2000). Towards robust distributed systems (Invited talk). Proceedings of the 19th Annual ACM Symposium on Principles of Distributed Computing.
- Vogels, W. (2009). Eventually consistent. Communications of the ACM, 52(1), 40-44.
- Gilbert, S., & Lynch, N. (2002). Brewer's conjecture and the feasibility of consistent, available, partition-tolerant web services. ACM SIGACT News, 33(2), 51-59.
- Kleppmann, M. (2017). Designing Data-Intensive Applications. O'Reilly Media.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →