События и очереди

3 мин чтения ·

Eventual Consistency: когда данные могут отставать, а когда — нет

Заказ подтвердили, а счётчик ещё не изменился. Где это нормально, где опасно и как согласовать задержки данных с обещаниями продукта.

Покупатель оформил заказ, получил подтверждение, а счётчик заказов в личном кабинете ещё не обновился. Через несколько секунд всё стало правильно. Технически ничего не сломалось. Но если речь не о счётчике, а об остатке денег на счёте, такая же задержка уже может привести к неприятным последствиям.

В этом и смысл eventual consistency: разные представления данных могут некоторое время расходиться, а затем приходить к согласованному состоянию. Однако слово «потом» здесь нельзя оставлять без определения. Для бизнеса важны и допустимое время, и то, что пользователь успевает сделать до обновления.

Что именно отстаёт

Одна система принимает изменение, другие получают его через сообщения, репликацию или периодическую синхронизацию. Пока обновление в пути, разные участники видят разные версии. Это не обязательно потеря данных — просто результат ещё не распространён.

Например, склад подтвердил резерв, а поисковый каталог ещё показывает старое количество товара. Если клиент пытается оформить вторую покупку, система записи должна повторно проверить возможность резерва. Использовать отстающий поисковый индекс как единственный источник истины нельзя.

В некоторых сценариях достаточно показать «данные обновляются» или сразу отобразить подтверждённый результат действия. В других нужна строгая проверка в момент изменения, даже если список на экране обновляется позже.

Нужно ли клиенту видеть изменение сразу

У eventual consistency нет универсального допустимого времени. Лента уведомлений может отставать без серьёзных последствий. Статус заказа после оплаты потребует более внимательной коммуникации. Остаток доступных средств или предотвращение двойного списания — совсем другой уровень требований.

Важно различать гарантии. Можно обеспечить, чтобы пользователь после собственной записи читал её подтверждённую версию — это иногда называют read-your-writes. Можно сделать отдельные операции строго согласованными, а отчёты и поиск — асинхронными. Не нужно выбирать одну модель согласованности для всего продукта.

Нельзя компенсировать архитектурную неопределённость фразой «через какое-то время всё сойдётся», если бизнес не знает, что в это время разрешено пользователю.

Что делает систему действительно сходящейся

Отставание не исчезает само по себе. Если сообщение потерялось окончательно, обработчик перестал работать или конфликтующие записи разрешаются неправильно, система может так и не прийти к корректному состоянию.

Поэтому нужны надёжная доставка изменений, повторная обработка, идемпотентность, правила разрешения конфликтов и способ сравнить производные представления с источником истины. Для чтения отдельно стоит измерять возраст данных и отставание реплик.

Если применяется CQRS, команда должна уметь восстановить проекцию и объяснить, какие данные пользователь видит до её обновления. Параллельные изменения тоже требуют защиты: устаревшее событие не должно безусловно перезаписывать более новое состояние.

Как договариваться с бизнесом

Я бы не начинал с выбора базы данных. Сначала составил бы список пользовательских действий: где достаточно быстрого чтения, а где операция требует немедленной проверки актуального состояния. Затем зафиксировал допустимую задержку для каждого сценария и поведение продукта при превышении этого времени.

Вопрос «кто исправит рассинхронизацию?» должен иметь конкретный ответ. Нужны владелец результата, метрика отставания и процедура восстановления. Иначе архитектура может быть идеально асинхронной на бумаге и совершенно непредсказуемой для поддержки.

Eventual consistency — не разрешение показывать неправильные данные сколько угодно. Это сознательный выбор, где задержка дешевле глобальной координации, а последствия задержки контролируются.