Latency budget на собеседовании системного аналитика

Проверь себя · 1/3разбор после ответа
Нужно получить 20 самых новых событий из таблицы events (по времени event_time) и показать их в выдаче сверху. Какой запрос верный?

Что такое latency budget

Latency budget (бюджет задержки) — это общий SLA по времени ответа, разложенный на доли между всеми компонентами, через которые проходит запрос. Вы берёте целевую задержку для пользователя и распределяете её так, чтобы сумма частей не превышала целое. Каждый компонент получает свой лимит и отвечает за то, чтобы в него уложиться.

Общий бюджет p99: 500 мс
  - Проверка авторизации:      50 мс
  - Запрос в БД:              200 мс
  - Бизнес-логика:             50 мс
  - Вызов внешнего API:       150 мс
  - Сериализация и сеть:       50 мс

Смысл в том, что у каждой доли есть владелец. Если запрос в БД съедает 350 мс вместо своих 200 — весь бюджет превышен, даже когда остальные части идеальны. На собесе системного аналитика это любимая тема: вам дают целевой SLA и просят разложить его по системе, а потом объяснить, где можно выиграть время. Проверяют, что вы мыслите сквозным путём запроса, а не отдельными сервисами.

Разбивка по компонентам

Чтобы построить бюджет, нужно пройти по трассировке запроса и увидеть все шаги: балансировщик, авторизация, обращения к БД и кэшу, вызовы соседних сервисов, внешние API, сериализация ответа. Дальше вы распределяете общий лимит пропорционально ожидаемой работе на каждом шаге — тяжёлый запрос в БД получает больше, простая проверка токена меньше.

На что часто закладывают недостаточно бюджета:

  • Сетевые round-trip'ы. Каждый переход между сервисами — это сетевая задержка, и её систематически недооценивают. Пять последовательных вызовов по 10 мс сети — это уже 50 мс «из воздуха».
  • Промахи кэша. Бюджет нельзя считать по «горячему» пути, где всё в кэше. Нужно закладывать и сценарий cache miss, когда придётся идти в БД.
  • Ретраи. Повтор упавшего запроса — это дополнительная задержка поверх исходной. Один ретрай может удвоить время шага, и это должно быть в бюджете.

Последовательные и параллельные вызовы

Ключевая механика, которую проверяют на собесе: как складываются задержки. Если вызовы идут последовательно (следующий ждёт результата предыдущего), их времена суммируются.

A → B (50 мс) → C (100 мс) → D (50 мс) = 200 мс

Если вызовы независимы и запускаются параллельно, итоговая задержка равна не сумме, а максимуму из них — вы ждёте самый медленный.

A → [B, C, D] параллельно → max(50, 100, 50) = 100 мс

Отсюда простой, но сильный приём: там, где вызовы не зависят друг от друга, их нужно распараллеливать. В примере выше это ужимает 200 мс до 100 мс без единой оптимизации самих сервисов. На собесе стоит явно проговорить, какие шаги можно запустить одновременно, а какие обязаны идти по очереди из-за зависимости по данным.

Готовься к собесу аналитика как в Duolingo
10 минут в день — SQL, Python, A/B, метрики. 1700+ вопросов в Telegram
Открыть Карьерник в Telegram

Длинные цепочки вызовов

Длинные синхронные цепочки RPC — типичная беда микросервисов: задержки складываются, и общий ответ растёт линейно с длиной цепочки.

Сервис A → B → C → D → E
по 50 мс на звено → 250 мс суммарно

А сверху накладываются ретраи и вероятность отказа: чем длиннее синхронная цепочка, тем выше шанс, что где-то в середине что-то замедлится или упадёт, и тем больнее это бьёт по хвостовым задержкам (p99).

Решение — разрывать синхронную связность. Часть работы уносят в асинхронные события: сервис не ждёт ответа по цепочке, а публикует событие и отвечает сразу. Либо агрегируют независимые вызовы в параллель вместо длинной последовательности. На собесе хороший ответ звучит так: «сократить длину синхронной цепочки, независимые шаги распараллелить, некритичную к моменту работу вынести в асинхронную обработку».

Стратегии оптимизации

  • Кэширование. Убирает повторные вычисления и походы в БД с горячего пути. Самый быстрый выигрыш, но нужно закладывать в бюджет и промахи кэша.
  • Асинхронность. Всё, что не обязано считаться в момент ответа (уведомления, аналитика, тяжёлые пересчёты), выносится из синхронного пути в фоновую обработку.
  • Батчинг. Несколько мелких операций объединяются в один запрос — вместо N round-trip'ов один. Прямо лечит N+1 и болтливые вызовы к БД.
  • Пул соединений. Переиспользование установленных соединений вместо создания нового на каждый запрос экономит на рукопожатии (особенно TLS).
  • Сжатие. Меньше байтов по сети — меньше времени на передачу, полезно для больших ответов.
  • Edge / CDN. Ответ или статика ближе к пользователю физически, короче сетевой путь и меньше RTT.
  • Реплики на чтение. Распределяют нагрузку чтения, снимая давление с основной БД и уменьшая её задержку под нагрузкой.
  • Предвычисление. Материализованные представления и заранее агрегированные таблицы переносят тяжёлую работу из времени запроса в фон.

Связанные темы

FAQ

Почему бюджет считают по p99, а не по среднему времени ответа?

Среднее прячет хвост: половина пользователей может получать ответ за 100 мс, а несчастливые 1% — за секунды, и именно они уходят и жалуются. p99 показывает опыт худших запросов, а SLA как раз про них. Поэтому бюджет закладывают на p99, а не на mean.

Как параллельность помогает уложиться в latency budget?

Последовательные вызовы суммируют задержки, а параллельные независимые вызовы дают только максимум из них. Распараллелив три вызова по 50, 100 и 50 мс, вы получаете 100 мс вместо 200 — без оптимизации самих сервисов. Это первый, что стоит предложить на собесе после того, как выделили независимые шаги.

Что делать, если бюджет не сходится — сумма компонентов больше SLA?

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

Нужно ли закладывать в бюджет ретраи и промахи кэша?

Да. Бюджет по «счастливому» горячему пути обманчив. Реальный p99 включает cache miss (поход в БД) и ретраи упавших вызовов, каждый из которых добавляет задержку. Если их не учесть, на проде вы стабильно будете вылетать за SLA.

Это официальная информация?

Нет. Статья основана на индустриальных практиках проектирования производительности и распределённых систем. Конкретные цифры бюджета зависят от системы, нагрузки и требований бизнеса.


Тренируйте системный анализ — откройте тренажёр с 1500+ вопросами для собесов.