How to make things slower so they go faster
Как замедлить, чтобы ускорить
Синхронный спрос — когда множество клиентов действуют одновременно.
Пропускная способность μ, фоновая нагрузка λ₀, запас H = μ − λ₀.
M клиентов, синхронизированных по крону, кэшу или перезапуску, превышают H, образуют очереди, таймауты, ретраи и инцидент.
Цель — размазать пик или безопасно его слить, сохраняя справедливость и лимиты.
Источники выравнивания:
- естественные — часы, TTL, SDK-таймеры;
- индуцированные — деплой, рестарт, сброс кэша, обновление токенов;
- внешние — DDoS, флеш-крауд.
Ограничения:
- мягкие — задержка в очереди;
- жёсткие — пулы соединений, дескрипторы, потоки.
Превышение даёт обрыв: ещё одно соединение → таймаут → ретраи → ещё больше нагрузки.
Важно, кто ждёт: онлайн-запросы требуют справедливости, офлайн — только пропускной способности.
Математика размагничивания
M действий равномерно в окне [0, W]:
ожидаемый пик M/W, средняя задержка W/2, произведение M/2 — константа.
Чем шире W, тем ниже пик, но выше средняя задержка.
Для выпуклой функции стоимости C(r) равномерное r(t)=M/W минимизирует ∫C(r)dt (неравенство Йенсена).
Равномерный джиттер оптимален и справедлив.
Практика
-
Детерминированные границы:
- M/W ≤ H ⇒ W ≥ M/H;
- (M/W)·s ≤ K ⇒ W ≥ Ms/K (s — p95 времени обработки, K — свободная конкурентность).
-
Вероятностные границы:
Пусть N ~ Poisson(M/W). Требуем Pr{N > H} ≤ ε.
Для H ≳ 50 нормальное приближение даёт
λε ≈ ((-z₁₋ε + √(z₁₋ε² + 4(H+0.5)))/2)²,
W ≥ M/λε.
Для малых H или ε считать точный хвост Пуассона. -
Подсказки от сервера:
- Retry-After: Δ → джиттер в [Δ, Δ+W];
- rate-limit: R оставшихся запросов до сброса через Δ → λadm = min(H, R/Δ) → W ≥ M/λadm.
-
Продуктовые ограничения:
- дедлайн D ⇒ W ≤ D;
- p95 добавленной задержки ≤ L ⇒ W ≤ L/0.95.
Минимально-ожидающая политика
Выбрать наименьший W, удовлетворяющий всем нижним границам и не превосходящий верхние.
Если невозможно — добавить мощность или ослабить ограничения.
Комментарии (26)
- Участники обсуждают парадоксы, при которых «ускорение» ведёт к замедлению: парадокс Браесса, парадокс Джевонса.
- Подчёркивается мысль «slow is smooth, and smooth is fast»: медленные, точные действия итогом быстрее и эффективнее, будь то код, строительство или музыка.
- Пример Facebook: задержки и очереди используются как ресурс — задачи выполняются ближе к максимально допустимому времени отклика, повышая общую пропускную способность.
- Упоминаются практические техники регулировки скорости: nanosleep по объёму данных, параметризуемые «тормоза» в долгих процессах.
- Итог: оптимизация — это не просто «делать быстрее», а баланс скорости, точности и использования ограниченных ресурсов.
Good system design 🔥 Горячее 💬 Длинная дискуссия
Всё, что я знаю о хорошем системном дизайне
Системный дизайн — это то, как мы собираем сервисы, а не строки кода. Его примитивы: серверы, БД, кэши, очереди, прокси и т.д.
Хороший дизайн выглядит скучно: ничего не ломается, задачи решаются проще, чем ожидалось. Сложные системы с CQRS, консенсусом и прочими фокусами часто компенсируют плохие решения. Сложное должно расти из простого, а не строиться сразу.
Состояние и его минимизация
Сложность — в управлении состоянием. Stateless-сервисы (например, конвертер PDF → HTML) перезапускаются и живут вечно. Stateful-сервисы могут «испортиться» и требуют ручного лечения. Поэтому:
- Один сервис пишет в БД, остальные общаются с ним по API/событиям.
- Чтение иногда проще делать напрямую, но писать — только через «владельца» данных.
Базы данных
Главный компонент.
- Схема: читаемая человеком, достаточно гибкая, но не «всё в JSON».
- Индексы: под самые частые запросы, не больше.
- Узкие места: обращения к БД часто тормозят всё.
Комментарии (348)
- Сложность ≠ хороший дизайн: большинство участников согласны, что переусложнённые системы часто свидетельствуют о слабом проектировании, но на собеседованиях это лучше не озвучивать.
- Главный критерий — пригодность (fit for purpose): универсальных «правильных» архитектур не существует, нужно исходить из задач команды и бизнеса.
- Простота и KISS ценятся выше модных паттернов; монолит или «скучные» технологии часто эффективнее микросервисов и самописных очередей.
- Ключевые боли — синхронизация состояний и транзакционность между сервисами; чем меньше распределённого состояния, тем проще жить.
- Не забывать людей: Conway’s Law и топология команд влияют на архитектуру не меньше, чем технические решения.