Производительность
Batching: построй и закали ingest-пайплайн
Читать про окна, backpressure и poison-message — не то же самое, что гонять пайплайн, который их переживает. Построй небольшой путь батчинг-ingest, настрой его окно под latency-SLO, затем загони в каждый production-сбой и докажи, что защита держит — с доказательством на каждом шаге.
Преврати ментальную модель юнита в воспроизводимый инженерный цикл: амортизируй фиксированную цену окном size+time, настрой это окно под SLO по измеренным данным, затем закали пайплайн против переполнения, poison-message и decompression bomb — проверяя каждое числами before/after.
Построй ingest-пайплайн, чей горячий путь доминируется фиксированной ценой на операцию, забатчь его за окном size+time, настроенным под заявленный p99-SLO, и закали против трёх production-сбоев — переполнение, poison-message и decompression bomb — доказывая выигрыш throughput и каждую защиту измерениями, а не оценками.
- Таблица before/after: throughput (элементов/с), амортизация фиксированной цены (syscall'ов, round-trip'ов или коммитов на элемент) и p99 end-to-end latency — измеренные под одной нагрузкой, где batching даёт явный выигрыш throughput при p99 под SLO.
- Доказательство, что окно настроено, а не угадано: гистограмма размера батча наполняется около max-size на пике (throughput-bound), а таймер ограничивает latency при низкой нагрузке, с p99 из bursty-реплея под SLO.
- Демо переполнения: график или лог, показывающий ограниченную очередь, применяющую выбранную политику под нагрузкой продьюсер>консьюмер, счётчик drop'ов, ведущий себя как задумано, и unbounded-вариант, OOM-killed для контраста.
- Демо poison-message: лаг консьюмера остаётся плоским, пока split-and-retry изолирует и dead-letter'ит плохую запись и коммитит остальные — против baseline abort-whole-batch, чей лаг спиралит.
- Демо decompression bomb: post-decompression-cap отклоняет разворачивающийся payload с ошибкой ограниченной памяти вместо OOM процесса.
- Абзац write-up: какую фиксированную цену ты амортизировал, почему выбрал своё окно и политику переполнения из SLO и tradeoff'а потерянный-элемент-против-latency, и на какую метрику ты бы алертил первой.
- Сделай окно адаптивным: гоняй AIMD-контур на наблюдаемом p99 против SLO (расти окно, когда p99 < SLO − margin, дели пополам на breach) и покажи, что он бьёт лучшее статическое окно в обоих режимах — низкой и высокой нагрузки.
- Добавь компрессию и докажи, что ей нужен batching: сравни байты на проводе при linger=0 (крошечные батчи, кодек бесполезен) против наполненного батча (компрессия 2–4×), подтвердив, что кодек кусается только на толстых батчах.
- Добавь DLQ плюс re-drive job: после изоляции poison-записи почини нижележащий баг схемы и реплейни DLQ обратно в основной поток, показав нулевую потерю данных end to end.
- Воспроизведи stall Nagle/delayed-ACK на 40 мс на request/response-варианте пути (маленькая запись, затем ожидание), затем почини его через TCP_NODELAY и покажи, как пол latency исчезает.
Это цикл, который ты будешь гонять на каждом реальном пути батчинга: подтверди, что фиксированная цена доминирует, добавь окно size+time, инструментируй size/wait/depth/drops, затем настрой окно от SLO и валидируй на реплее bursty-трафика — никогда не гонись за max throughput на доске. Потом закали его, потому что каждое свойство эффективности — множитель сбоя: ограничь очередь и выбери block/drop/spill из tradeoff’а потерянный-элемент-против-latency, изолируй poison-message через split-and-retry плюс DLQ и валидируй границу батча post-decompression и per-item. Сделав это раз на игрушечном пайплайне, ты делаешь production-версию мышечной памятью.