Не запускайте задание: сброс нагрузки для плановых пакетных работ
Одно тяжёлое пакетное задание на уже загруженном хосте положило наш прод. Починили не ускорением задания, а правилом: если машина перегружена или не хватает диска, плановое задание не стартует, записывает причину и пробует снова на следующем тике.
🎯 Для Любой, кто запускает cron-задания, бэкфиллы или пакетные работы агентов рядом с рабочим сервисом
- Почему занятый хост должен отказываться от нового пакетного дела
- Небольшая обёртка, которая сбрасывает нагрузку, блокирует и понижает приоритет
- Как читать журнал отказов как сигнал о ёмкости
💥 Что случилось
8 июля 2026 тяжёлый прогон тестов стартовал на уже занятом хосте. Нагрузка дошла примерно до восьмисот процентов на восьми ядрах, и вся машина, включая рабочие сервисы, зависла. С самим заданием всё было в порядке. Неправильным был момент запуска.
Второй инцидент 14 сентября 2026 имел иную причину, но ту же форму: диск дошёл до девяносто семи процентов, потому что бэкапы не ротировались, и каждое задание, писавшее в это окно, ухудшало положение.
🛑 Правило
Плановое задание не стартует при перегрузке хоста. Оно записывает пропуск и завершается успешно, а планировщик запустит его на следующем тике. Данные догонятся позже, а прод продолжит дышать. Наша обёртка перед запуском проверяет две вещи: минутную нагрузку относительно лимита, по умолчанию шесть на этом восьмиядерном хосте, и свободное место на диске относительно минимума, по умолчанию два гигабайта.
Если обе проверки проходят, обёртка запускает задание под эксклюзивной блокировкой, чтобы две копии не пересеклись, с пониженным приоритетом процессора и приоритетом простоя для диска. Ещё одно правило обёртки: если сама утилита проверки диска сломана, проверка диска пропускается. Сломанный инструмент не должен останавливать все задания хоста.
🕵️ Сторож, который никогда не убивает
Отдельный сторож запускается каждые пять минут и пишет состояние в файл. Он выводит мягкий и жёсткий пороги нагрузки из числа ядер. За жёстким порогом он понижает приоритет известных пакетных процессов и никогда ничего не убивает. На 3 ноября 2026, 21:53 UTC он сообщал 8 ядер, мягкий порог 4,8 и жёсткий 6,8, последнее действие — «ok».
Мы также перераспределили доли процессора: плановые задания вместе могут занимать не больше шести из восьми ядер и имеют низкий вес, а рабочие сервисы — более высокий.
📊 Журнал отказов
Обёртка дописывает строку каждый раз, когда отклоняет задание. С 30 июля 2026 в журнале 8 415 строк по 67 разным заданиям, и четыре самых частых задания дают 4 938 из них. Самый загруженный день — 15 октября 2026: 1 155 отклонённых запусков.
Читайте это как сигнал о ёмкости, а не как сбой. Тысячи отклонённых запусков означают, что хост полон в моменты, на которые назначены задания, и расписание нужно разнести или работу перенести на другую машину. Они же значат, что защита работает: каждый из них мог навредить проду.
🛠️ Практика: оберните тяжёлые задания
- Перечислите плановые задания и отметьте тяжёлые: тесты, бэкфиллы, оптимизаторы, выгрузки.
- Напишите обёртку, которая проверяет нагрузку и свободный диск и тихо завершается со строкой в журнале, если что-то вне нормы.
- В той же обёртке добавьте эксклюзивную блокировку, пониженный приоритет процессора и приоритет простоя для диска.
- Поставьте каждое тяжёлое задание за обёртку. Делайте это по файлам, а не правкой общей таблицы расписания.
- Добавьте сторож, который записывает нагрузку и понижает приоритет пакетных процессов, но никогда их не убивает.
- Просматривайте журнал отказов раз в неделю. Переносите или разносите задания, которые отклоняются чаще всего.
✅ Проверьте себя
- Запустите «пожиратель» процессора, затем обёрнутое задание. Задание отклонено, а в журнале видна цифра нагрузки.
- Запустите одно обёрнутое задание дважды. Вторая копия завершается сразу.
- Заполните диск ниже вашего минимума на тестовом хосте. Пишущие задания отклоняются.
- Вы можете сказать, какое задание отклонялось чаще всего на прошлой неделе.
🚧 Когда это не работает
- Задания, которые обязаны выполниться. Задание с важным сроком, например бэкап, нельзя пропускать вечно. Добавьте максимум пропусков.
- Постоянная перегрузка. Если хост всегда выше лимита, не запускается ничего. Это значит, что нужна ёмкость, а не заниженный лимит.
- Скачущие сервисы. Короткий всплеск может отклонить задание, которое бы поместилось. Используйте короткое скользящее среднее.
- Приоритет — не изоляция. Задание с низким приоритетом всё равно может использовать память и диск. Лимиты по группам сильнее.
- Молчаливый пропуск. Если журнал никто не читает, задание можно потерять на недели. Поднимайте тревогу, если задание не выполнялось сутки.
📊 Доказательства
| Что измерено | Строки и задания в журнале отказов, файл состояния сторожа и пороги в обёртке |
| Когда | 3 ноября 2026, 21:53 UTC |
| Артефакт | Журнал отказов и файл состояния сторожа в нашем закрытом развёртывании; скрипт обёртки и его заметка о решении |
| Ограничение | Журнал считает отклонённые запуски, а не предотвращённый вред. Два инцидента взяты из наших записей об инцидентах |
➡️ Дальше
Спланируйте, что делать, если всё же сломалось, по Плану реагирования для небольшой команды и прочитайте Восстановление после сбойного, зависшего или неопределённого запуска.
Источники
- План реагирования для небольшой команды: шаги реагирования.
- Восстановление после сбойного, зависшего или неопределённого запуска: восстановление.
- Расходы, бюджеты и лимиты: лимиты.
- Развилки доступа агента к shell: варианты доступа к shell.
🔗 Связи статьи
Открыть полный граф знаний ↗Связи опубликованных статей. Выберите узел, чтобы открыть статью у заголовка.
Связи статей · клавиатура / текст
Та же тема
- Векторная база — это карта, а не источник: чему нас научил поиск
- Когда неизвестно, сколько стоил вызов модели: заморозка, затем сверка
- Как разбить большую задачу для дешёвой модели: урок 24 000 байт
- Навыки, MCP-инструменты и правила: три способа дать агенту возможности
- Восемь ошибок наших агентов в shell и git и правило на каждую
- Несколько агентов, один репозиторий: правила владения из реальных инцидентов
Следующие шаги
Связанные материалы
Векторная база — это карта, а не источник: чему нас научил поиск
Векторная база находит фрагменты, близкие по смыслу к вашему вопросу. Она не знает, какие из них верны или актуальны. Считайте каждое попадание указателем: откройте названный файл, сверьте хэш, а числа берите из артефакта, а не из найденного абзаца.
ИИ-агенты и MCP простыми словамиКогда неизвестно, сколько стоил вызов модели: заморозка, затем сверка
Иногда вызов модели обрывается по таймауту, и вы не знаете, списал ли провайдер деньги. Никогда не записывайте это как ноль. Пометьте как неопределённое, остановите новые платные вызовы и пусть названный человек сверит это с выпиской провайдера. Отказы до генерации — исключение.
ИИ-агенты и MCP простыми словамиКак разбить большую задачу для дешёвой модели: урок 24 000 байт
Дешёвая модель хорошо справляется с одной небольшой чёткой задачей и плохо — с большой кучей. Мы ограничиваем задачу 24 000 байт и отклоняем большие до вызова любой модели. Режьте по единицам — один файл или одна страна на задачу — и проверяйте размер до запуска.
ИИ-агенты и MCP простыми словамиНавыки, MCP-инструменты и правила: три способа дать агенту возможности
Агенты получают способности по-разному. Правило ограничивает, что они делают, навык говорит, как делать работу, а MCP-инструмент позволяет вызывать функцию. У каждого свой риск, поэтому объявляйте все три в реестре и проверяйте тестом, что ничего не существует вне списка.
💬 Комментарии