2026 узел Apple Silicon 7×24: матрица справедливости batch — launchd ThrottleInterval, nice и политика ввода-вывода для доли завершения длинных задач

Время чтения: 8 минут

Когда на одной Mac Mini соседствуют несколько периодических агентов launchd, «справедливость» измеряется не лозунгом, а долей сессий, которые реально доходят до конца без хвоста задержек. Оператору нужны измеримые рычаги: минимальный зазор между успешными прогонами одной метки, смещение календарных минут и осознанное понижение приоритета CPU для длинных участков. Документируйте часовой пояс и границы ночного коридора так же строго, как версии скриптов, иначе регрессии воспроизводятся хуже инцидентов по железу.

Ниже — матрица и чек-лист по ThrottleInterval, nice и политике записи без ionice: сначала софт, потом расширение узла — иначе растёт бюджет без роста доли завершения. См. очереди 7×24, ночной workflow_dispatch, водораздел APFS. Арендабез обязательного входа на этапе оформления, где это доступно.

Почему «всё по cronу» всё равно сталкивается на одном хосте

  1. Совпадение по минуте. StartCalendarInterval у разных меток может дать одновременный старт; два тяжёлых задания делят NVMe и растягивают wall-clock при формально успешных выходах.
  2. Только nice. CPU-приоритет не сериализует писателей на одном томе: очередь записи всё равно переполняется.
  3. Хвост без зазора. Без 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, чтобы два полных прохода не читали диск синхронно.

Шесть шагов внедрения без скачка железа

  1. Инвентаризация меток launchd с StartCalendarInterval или StartInterval плюс длительность последних пяти прогонов из журналов.
  2. Теги CPU, диск, смешанный; писатели отдельно от читателей.
  3. Минутные корзины без пересечений; ThrottleInterval — если коллизии после смещений.
  4. nice и кап воркеров в скрипте до заказа большего числа ядер.
  5. LowPriorityIO точечно после теста на копии; одно изменение за итерацию.
  6. Откат: копии 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 и ночные коридоры записи; бюджет под контролем при измеримой политике. Узел: аренда, тарифы, главная.

Узел Mac под дисциплинированный batch launchd

RunMini: разнесённые дорожки batch. Главная, тарифы, помощь, арендабез обязательного входа при оформлении где доступно.

Закладки: главная, блог.

Mac Mini под batch и launchd