Вопрос проверяет умение вынести дорогую работу из критического пути: построить асинхронный пайплайн, обеспечить актуальность данных и управлять задержкой обновления.
Тяжёлые вычисления выносят в отдельный фоновой процесс: либо по расписанию (batch), либо по событиям (stream). Сервис в онлайне читает уже готовые результаты из быстрой витрины (Redis/БД под чтение). Важно определить допустимую “задержку свежести” и построить обновления так, чтобы данные были достаточно актуальны. Для устойчивости нужны идемпотентность обработчиков, повторяемость вычислений и контроль отставания (lag).
Предрасчёт — это конвейер: входные изменения → вычисление → запись результата → быстрый онлайн-рид.
Сначала фиксируем:
какие вычисления “тяжёлые” (CPU/IO)
какие данные нужны на запросе
допустимая свежесть (например, “не старше 5 минут”)
Определение: Freshness — насколько “свежими” должны быть данные на момент ответа (задержка между изменением и обновлением витрины).
Есть два базовых способа:
Batch по расписанию
проще, предсказуемо
может быть “ступеньками” по свежести
Event-driven по изменениям (Kafka)
обновления ближе к реальному времени
сложнее, но лучше для динамичных данных
Типичная схема:
Продьюсер пишет событие изменения (например, “пользователь сделал действие”)
Консьюмер читает события и обновляет агрегаты/витрину
Онлайн-сервис читает готовый результат
Ключевые аспекты:
порядок обработки (per key ordering), если важно
дедупликация/идемпотентность
ретраи и DLQ (dead letter queue) для “ядовитых” сообщений
Определение: Idempotent consumer — обработчик, который можно безопасно повторить, не ломая результат.
Способы:
хранить обработанные event-id (дорого, но надёжно)
обновлять агрегаты “по факту состояния”, а не “прибавь всегда” (зависит от домена)
делать записи в витрину с version/updated_at и принимать только “самое новое”
Витрина — это место, откуда читает онлайн:
Redis для быстрых ключевых чтений
отдельная таблица/коллекция под чтение
иногда материализованные представления (если поддерживаются)
Важно:
формат должен быть “готов к ответу” или требовать минимальной склейки
Нужно мониторить:
consumer lag (насколько отстали обработчики)
скорость обработки и ошибки
Если лаг растёт:
включать деградацию (stale-данные, fallback)
масштабировать консьюмеров (если порядок позволяет)
Предрасчёт позволяет держать быстрый SLA: тяжёлое считаем асинхронно (batch или Kafka-события), складываем результат в витрину для чтения, а онлайн-запрос только читает готовые данные. Критично заранее определить допустимую freshness и обеспечить идемпотентность обработчиков.