Реплики расходятся на время и сходятся потом. Компромисс, на который идут ради доступности и скорости записи.
Ключевые тезисы
- : при сетевом разделении выбирают между согласованностью и доступностью — третьего нет.
- Кворумы W + R > N дают строгую согласованность чтения без блокировок на запись.
- Расхождения чинят фоновой синхронизацией: находят различия, gossip разносит состояние.
Какую задачу решает
Данные лежат на нескольких машинах. Запись пришла на одну — что видят остальные? Если ждать, пока все подтвердят, запись становится медленной и падает вместе с любой из реплик. Если не ждать, то какое-то время реплики расходятся, и читатель может получить устаревший ответ.
формулирует, что выбора здесь всего два. При разрыве сети между узлами система либо отказывается отвечать, пока не восстановится связность (сохраняя согласованность), либо отвечает тем, что знает (сохраняя доступность). Одновременно и то и другое невозможно — это не про качество реализации, а про физику.
— сознательный выбор второго. Реплики расходятся ненадолго и сходятся потом: фоновая синхронизация находит различия и распространяет их. Ценой недолгой неточности покупается запись, которая не останавливается никогда.
Пользователь добавил товар с телефона, через секунду — другой товар с ноутбука. Запросы ушли на разные реплики. При разрешении конфликта по времени записи побеждает более поздняя версия, и первый товар просто исчезает: не сломался, а был перезаписан целиком. Ошибка не в базе, а в модели данных — корзина хранилась как единое значение. Решение: хранить её как множество операций добавления и удаления. Множества сливаются объединением, конфликта не возникает вовсе, и оба товара остаются. Это и есть смысл бесконфликтных типов данных: подобрать структуру, для которой слияние определено однозначно.
Подробный разбор
Формулировку «выберите два из трёх» часто понимают неверно. Разделение сети (P) — это не свойство, которое выбирают, а событие, которое рано или поздно случается. Реальный выбор делается в разрыва: отвечать устаревшими данными или не отвечать вовсе.
| Выбор при разрыве | Что делает система | Примеры |
|---|---|---|
| Согласованность (CP) | отказывает в обслуживании меньшей части | , etcd, |
| Доступность (AP) | отвечает тем, что знает локально | , DynamoDB, Riak |
Более практичная формулировка — PACELC: при разрыве (P) выбирают между A и C, а в нормальном режиме (E) — между задержкой (L) и согласованностью (C). Второй выбор делается постоянно, а не раз в год, и потому важнее.
Запись подтверждается, когда её приняли реплик; чтение опрашивает реплик. Если сумма больше числа реплик , множества обязательно пересекаются — значит, читатель увидит хотя бы одну реплику с последней записью.
| N | W | R | Свойства |
|---|---|---|---|
| 3 | 3 | 1 | быстрое чтение, запись падает при потере любой реплики |
| 3 | 2 | 2 | сбалансированно, переживает потерю одной реплики |
| 3 | 1 | 1 | быстро и доступно, но чтение может быть устаревшим |
| 3 | 1 | 3 | быстрая запись, медленное чтение |
Пересечение гарантирует, что среди прочитанных есть свежая версия, — но выбрать её из нескольких надо уметь. Отсюда необходимость версионирования: без него читатель не отличит новое от старого.
Сравнивать версии по времени записи ненадёжно: часы на разных машинах расходятся на десятки миллисекунд, а сетевые — больше. Версия «из будущего» перезапишет актуальные данные и никто не заметит.
часы решают это без физического времени: у каждой реплики свой счётчик, версия — вектор счётчиков. Версия A новее B, если все её компоненты не меньше, и хотя бы одна строго больше.
[2, 1, 0] против [1, 1, 0] — первый новее, конфликта нет. [2, 1, 0] против [1, 2, 0] — ни один не доминирует: значит, записи произошли независимо, это настоящий конфликт, и его надо разрешать логикой приложения. [2, 1, 0] против [2, 1, 0] — одна и та же версия. Ценность в том, что третий случай отличается от второго: система знает, когда она действительно не может решить сама.
Две реплики хранят по миллиону ключей и разошлись в пяти. Сравнивать всё — гигабайты трафика. строит хеши по диапазонам: лист — хеш куска данных, узел — хеш своих детей.
- Сравнить корневые хеши. Совпали — реплики идентичны, обмен закончен одним числом.
- Не совпали — сравнить хеши детей и спуститься только в различающиеся ветки.
- Дойти до листьев и передать только реально расходящиеся куски.
Объём обмена получается логарифмическим по числу различий, а не линейным по объёму данных. Тот же приём работает в git, в BitTorrent и в блокчейнах — везде, где надо сверить большие наборы через сеть.
Как узел узнаёт, что в кластере появился новый сосед или упал старый? Централизованный реестр становится единой точкой отказа. обходится без него: каждый узел раз в секунду выбирает случайного соседа и обменивается с ним состоянием.
- Информация расходится по кластеру за раундов — как эпидемия.
- Нет единой точки отказа и нет координатора.
- Трафик равномерный и предсказуемый: каждый узел говорит с одним соседом за раунд.
Плата — и отсутствие , когда «все точно узнали». Поэтому годится для обнаружения членства и отказов, но не для операций, требующих согласия: для них заводят отдельный сервис координации.
Где применяется
- Каталоги и профилиСекунда рассинхронизации в описании товара никому не вредит.
- Счётчики и лайкиТочное значение в моменте не требуется, важна сходимость.
- Гео-распределённые сервисыЖдать подтверждения из другого континента дороже, чем допустить расхождение.
- Кеши Модель переживёт слегка устаревший , а простой — нет.
Плюсы, минусы и альтернативы
Плюсы
- Запись доступна, даже когда часть кластера недоступна.
- не зависит от самой медленной реплики.
- Горизонтальное масштабирование без координатора.
Минусы
- Читатель может увидеть устаревшие данные — приложение обязано это учитывать.
- Конфликты записи приходится разрешать явно, и «последний выигрывает» теряет данные.
- Отладка тяжёлая: ошибка воспроизводится только при определённом порядке событий.
Брать, если
- Доступность важнее мгновенной точности.
- Операции коммутативны или конфликт разрешается однозначно.
Не брать, если
- Деньги, остатки на складе, уникальность идентификаторов — там нужна строгая согласованность.
- Логика приложения не переживает чтения устаревшего значения.
Чем заменяют
Видеолекции
Записи университетских курсов, где эта тема звучит. Ссылка открывает запись с той секунды, где о ней говорят, — искать по трёхчасовой лекции не нужно.
Всё, что названо в описании, разобрано здесь же или в соседней теме — переходы под каждым определением.
Теорема CAP
При сетевом разделении выбирают между согласованностью и доступностью.
Разбор ниже: Теорема CAP по существуВекторные часы
Способ понять, какая версия новее и не расходятся ли они в принципе.
Разбор ниже: Векторные часыДерево Меркла
Хеш-дерево диапазона: позволяет найти различие между репликами, не пересылая все данные.
Разбор ниже: Деревья МерклаGossip-протокол
Узлы случайно обмениваются состоянием с соседями — так информация расходится по кластеру.
Разбор ниже: Gossip-протоколСпрашивают на собеседовании: Arenadata — Платформа данных.
Тема встречается в тесте по направлениям — ошибки приведут обратно на эту страницу.
Глава «Инженерия данных» последний раз правилась . Нашли ошибку — напишите.