Сервис читает с реплик и обещает: данные не старше пяти секунд. Как определить, можно ли безопасно ответить с конкретной реплики?
Нужно проверять не время последнего изменения конкретного объекта, а доказанный момент, до которого реплика применила все записи из источника. Реплика может ответить только тогда, когда её подтверждённая позиция отстаёт от текущей позиции источника не более чем на пять секунд с учётом неопределённости часов. Если это нельзя доказать, запрос следует задержать, направить на более свежую реплику или отклонить.
Ограничение устаревания появилось как компромисс между строгим чтением из лидера и быстрым чтением из географически удалённых реплик. Полностью синхронная репликация уменьшает риск устаревших данных, но повышает задержку записи и снижает доступность при проблемах связи.
Гарантия bounded staleness позволяет заранее задать допустимую границу свежести. Она особенно полезна, когда чтение может быть слегка устаревшим, но не должно отставать от актуального состояния дольше установленного интервала.
Простая проверка времени последней применённой записи ненадёжна. Если в системе давно не менялся конкретный ключ, его версия может быть старой по времени, но при этом полностью актуальной; наоборот, реплика может иметь свежую запись по этому ключу, оставаясь отсталой по другим записям, влияющим на общее состояние.
Кроме того, локальные часы узлов могут расходиться, а сообщения могут задерживаться или приходить неравномерно. Если реплика считает себя свежей только по собственному времени, она может нарушить обещание и вернуть данные, фактически устаревшие более чем на пять секунд.
Источник должен публиковать упорядоченную позицию состояния: например, монотонный номер журнала, логическую временную метку или подтверждённый commit time. Реплика сообщает не только прочитанные данные, но и safe point — границу, до которой она гарантированно применила все необходимые записи.
Система сравнивает текущую позицию источника с safe point реплики. Если разница укладывается в пять секунд, чтение допустимо. Если источник и реплика используют физическое время, расчёт должен учитывать максимальную погрешность синхронизации часов; безопасная система добавляет этот запас или применяет консервативную оценку.
Если условие не выполняется, есть три основных варианта: подождать продвижения реплики, выбрать реплику с меньшим отставанием или прочитать из лидера. Отклонение запроса предпочтительнее нарушения SLA свежести, если задержка или недоступность чтения недопустимы для бизнес-операции.
Важно различать bounded staleness и гарантию чтения последней записи. Первая допускает ограниченное отставание, а вторая требует более сильной гарантии и часто нуждается в координации с лидером или кворумом. Ограничение в пять секунд также не означает, что каждая отдельная запись будет видна ровно через пять секунд: это верхняя граница при корректной работе механизма отслеживания прогресса.
Сервис отображает остатки товаров в нескольких регионах. Реплика в регионе клиента обычно отстаёт на 200 миллисекунд, но во время сетевых проблем её задержка может вырасти до минуты.
Вариант с безусловным чтением из локальной реплики даёт низкую задержку, но нарушает обещание свежести при длительном отставании. Безусловное чтение из лидера сохраняет актуальность, но увеличивает задержку и создаёт зависимость от доступности удалённого региона.
Выбранное решение — хранить для каждой реплики подтверждённый safe point и использовать локальную реплику только при отставании не более пяти секунд. При превышении границы запрос сначала коротко ждёт восстановления прогресса, затем переключается на более свежую реплику или лидер. Это сохраняет локальную производительность в штатном режиме и не выдаёт заведомо слишком старые остатки во время сбоя.
Нет. Одних физических часов недостаточно из-за рассинхронизации, задержек доставки и отсутствия гарантии, что реплика применила все записи до указанного времени. Нужна подтверждённая позиция применения состояния, а при использовании временных меток — ещё и известная граница погрешности часов.
Для конкретного ключа его значение может оставаться корректным независимо от возраста версии, но общая гарантия свежести обычно относится к состоянию источника, а не только к этому ключу. Поэтому система должна явно определить семантику: достаточно ли актуальности самого объекта или требуется, чтобы реплика знала все изменения системы до заданного момента.
Одной проверки её среднего отставания недостаточно. Если клиент уже видел состояние до некоторой позиции, новая реплика должна быть способна обслужить чтение не раньше этой позиции либо запрос должен содержать соответствующий маркер прогресса. Иначе клиент может увидеть более старую версию, даже если новая реплика формально укладывается в общий лимит устаревания.