2026 узел Apple Silicon 7×24: матрица справедливости batch — launchd ThrottleInterval, nice и политика ввода-вывода для доли завершения длинных задач
Когда на одной Mac Mini соседствуют несколько периодических агентов launchd, «справедливость» измеряется не лозунгом, а долей сессий, которые реально доходят до конца без хвоста задержек. Оператору нужны измеримые рычаги: минимальный зазор между успешными прогонами одной метки, смещение календарных минут и осознанное понижение приоритета CPU для длинных участков. Документируйте часовой пояс и границы ночного коридора так же строго, как версии скриптов, иначе регрессии воспроизводятся хуже инцидентов по железу.
Ниже — матрица и чек-лист по ThrottleInterval, nice и политике записи без ionice: сначала софт, потом расширение узла — иначе растёт бюджет без роста доли завершения. См. очереди 7×24, ночной workflow_dispatch, водораздел APFS. Аренда — без обязательного входа на этапе оформления, где это доступно.
Почему «всё по cronу» всё равно сталкивается на одном хосте
- Совпадение по минуте. StartCalendarInterval у разных меток может дать одновременный старт; два тяжёлых задания делят NVMe и растягивают wall-clock при формально успешных выходах.
- Только nice. CPU-приоритет не сериализует писателей на одном томе: очередь записи всё равно переполняется.
- Хвост без зазора. Без ThrottleInterval и смещений короткая задача съедает тихий интервал после длинной.
Матрица: симптом и первичный рычаг
Сначала отделите CPU от диска по метрикам окна: загрузка ядер, глубина очереди к тому же тому, задержка чтения и записи. Таблица даёт стартовую осанку; финальные значения подтверждайте журналами длительности прогонов и не меняйте три параметра одновременно при отладке.
| Симптом | Первичный рычаг | Вторичный рычаг | Цель по завершению |
|---|---|---|---|
| Одинаковые джобы сталкиваются по часам | ThrottleInterval плюс смещение минут в StartCalendarInterval | Разные Label на разные «дорожки» | Гарантированный зазор между успешными прогонами одной метки |
| CPU у потолка, диск спокоен | nice или меньше воркеров внутри скрипта | Более редкий StartInterval там где допустимо | Сохранить отзывчивость переднего плана при движении batch |
| CPU низкий, часы растут, пишет много потоков | Снизить число параллельных писателей и разнести тяжёлые фазы | Опционально LowPriorityIO для проверенных бинарников | Предсказуемые метаданные APFS и очередь в ночном коридоре |
Чек-лист параметров для runbook
Цифры ниже ориентиры для одного узла Apple Silicon с несколькими ночными пайплайнами; фиксируйте их в репозитории рядом с plist и ссылкой на владельца метки.
| Рычаг | Стартовый диапазон | На что смотреть |
|---|---|---|
ThrottleInterval |
От тридцати до трёхсот секунд для «болтливых» успешных выходов | Другая метка всё ещё может пересечься по времени; держите смещения минут |
nice в обёртке |
Пять–пятнадцать для длинных CPU-хелперов batch | Если всё nice, голодание контрольного процесса; оставьте одну дорожку с базовым приоритетом |
Идея ionice на macOS |
Переносите в лимит потоков записи и смещение календарей | Штатного ionice нет; не закладывайте сценарии на Linux-семантику классов IO |
StartCalendarInterval минуты |
Семь–пятнадцать минут между тяжёлыми стартами в пределах часа | Локальное настенное время и переходы на летнее время документируйте явно |
Исполняемый каркас plist
Plist в LaunchAgents или системный каталог по политике; после правок — launchctl bootstrap и launchctl print.
<key>Label</key><string>com.example.batch_lane_night</string>
<key>ThrottleInterval</key><integer>120</integer>
<key>StartCalendarInterval</key>
<dict><key>Hour</key><integer>2</integer><key>Minute</key><integer>7</integer></dict>
<key>ProgramArguments</key>
<array>
<string>/bin/sh</string>
<string>-c</string>
<string>exec nice -n 12 /usr/local/bin/your-batch --writers=1</string>
</array>
<key>LowPriorityIO</key><true/>
<key>StandardOutPath</key><string>/var/log/your-batch.log</string>
<key>StandardErrorPath</key><string>/var/log/your-batch.err</string>
Ночное окно как усилитель политики
Ночь — низкая интерактивная нагрузка: сначала тяжёлая запись, затем проверки после зазоров ThrottleInterval. Внешние пачки событий сверяйте с локальными календарями launchd, как в гайде по ночному workflow_dispatch, чтобы два полных прохода не читали диск синхронно.
Шесть шагов внедрения без скачка железа
- Инвентаризация меток launchd с
StartCalendarIntervalилиStartIntervalплюс длительность последних пяти прогонов из журналов. - Теги CPU, диск, смешанный; писатели отдельно от читателей.
- Минутные корзины без пересечений; ThrottleInterval — если коллизии после смещений.
niceи кап воркеров в скрипте до заказа большего числа ядер.- LowPriorityIO точечно после теста на копии; одно изменение за итерацию.
- Откат: копии plist и центр помощи.
FAQ: диск против CPU
- Как отличить конкуренцию за диск от конкуренции за CPU
- Низкий CPU и рост времени при записи — диск. Насыщенные ядра при коротких очередях — CPU. Смесь — меньше писателей и nice на длинных CPU-хвостах.
- Заменяет ли ThrottleInterval nice
- Нет: зазор между выходами одной метки и приоритет одновременных процессов — разные плоскости; комбинируйте.
- Можно ли полагаться на ionice в macOS
- Стандартная macOS не поставляет ionice; переносите приоритет ввода-вывода в политику параллелизма записи, смещение окон launchd, опциональный LowPriorityIO и измеримые ночные коридоры без ожидания Linux-семантики классов.
Опорные пороги: ThrottleInterval 30–300 с после коллизий; nice 5–15 на длинный CPU; смещение минут 7–15; ionice на Darwin — капы писателей и календарь.
Итог. 7×24 batch на Mac Mini — дисциплина launchd, nice и ночные коридоры записи; бюджет под контролем при измеримой политике. Узел: аренда, тарифы, главная.