2026 облако Mac: диспетчируемые пулы сборок, шардирование задач, аффинити DerivedData и чеклист SLO очередей

Команды уже умеют класть pull request-ы на эластичные хостинговые раннеры, а ночные прогоны на выделенные Mac, но при добавлении нескольких узлов облака картина снова рушится: узлы ведут себя как отдельные VPS, Archive и лёгкие инкременты борются за одну очередь NVMe, а таймауты линковки читаются как дефекты продукта. Этот материал для 2026 года собирает четыре боли, матрицу шардинга, пять шагов внедрения, три метрики, понятные финансам, FAQ и структурированные данные, чтобы план ёмкости опирался на чеклист, а не на истории из чата.

Иллюстрация: шардированные CI-задачи на узлах Mac cloud с аффинити DerivedData

Содержание

1. Боли: привычки однохостового SSH, отсутствие шардов, дрейф аффинити, разный язык SLO

Переход с одного Mac по SSH к рою CI-узлов смещает доминирующие отказы с нехватки CPU к отсутствию явной политики расписания и кеша. Большие Swift-воркспейсы чувствительны к глубине очереди NVMe и локальности модульного кеша; без модели случайная дисперсия становится частью релизного ритма. Linux-сборки прошли тот же путь десять лет назад, только цепочка Apple гораздо жёстче наказывает общие корни, чем типичные GCC-конвейеры.

  1. SSH-инстинкты на многих хостах : инженеры по привычке заходят на любимую машину, тогда как планировщик раскидывает задачи случайно. Без меток и контрактов очередей журналы не сходятся с физическими путями, и инциденты плохо классифицируются.
  2. Нет шардов — ложный параллелизм : десять PR-сборок на восьми слотах выглядят параллельными, пока делят один DerivedData или общий том артефактов. Линковка упирается в диск и выстреливает редкими таймаутами.
  3. Дрейф аффинити : последовательные сборки ветки попадают на другие разделы или теряют подкаталоги кеша, инкрементные выигрыши пропадают, а обновления компилятора обвиняют зря.
  4. SLO только про CPU : когда финансы считают минуты, а платформа — зелёные галочки, встречи по масштабированию застревают. Доля очереди, разброс линковки и минуты ретраев должны жить на одной панели.

2. Матрица: зерно шарда, форма очереди, политика диска

Таблица дополняет материал о тёплых путях cold-warm Mac cloud и аффинити DerivedData и сравнение эластичных минут с baseline GitHub Actions и выделенный Mac для PR и nightly. Там выбираете уровень раннера, здесь решаете, как несколько собственных Mac сотрудничают. Для поминутного биллинга и глубины очереди смотрите также матрицу пула baseline, burst и минут. Оформите строку как артефакт дизайн-ревью: одна ось шарда на очередь, рядом разметка диска и потолок параллелизма, который вы отстаиваете при пике релиза.

Строки короткие, чтобы копировать в слайды. Добавьте фактические пути на полях, иначе дежурный гадает, какой слот держит какой SSD. Если продукт сомневается в отдельной очереди для матриц симулятора, наложите неделю глубины очереди и свободного места после последнего релиза: совпадение пиков линковки и свободного диска ниже двадцати процентов обычно отвечает в пользу разделения, даже если checkout станет дороже на пару минут.

Измерение Шард по схеме Шард по срезу тестов Пулы на метках
Главный выигрыш Снижает конкуренцию линковки на тяжёлой схеме Укорачивает хвост очереди параллельных тестов Физически изолирует Archive от лёгких задач
Главный риск Слишком много шардов раздувает checkout Неровные срезы дают ложнозелёные прогоны Дрейф меток требует гигиены автоматизации
Политика диска Подкаталоги по схеме и ночной GC Свой DerivedData на слот Двойное разделение build и артефактов на Archive-хостах
Подсказка SLO очереди Ограничить параллельные задачи на схему Привязать таймауты и потолки ретраев к срезу Держать глобально один-два параллельных Archive

3. Аффинити DerivedData и анти-стампед барьеры

Аффинити — это не магия, а повышение вероятности повторного использования модульного кеша. Дайте каждому слоту свой DERIVED_DATA_PATH, держите Archive в другой очереди, чем лёгкие инкременты, останавливайте новые Archive при свободном месте около пятнадцати процентов и публикуйте события в тот же Webhook-канал, что и пороги из наблюдаемости CI для очереди, диска и webhooks.

# Пример путей по слоту внутри пула Mac (иллюстрация)
export JOB_SLOT=${JOB_SLOT:-1}
export DERIVED_DATA_PATH=/Volumes/ci/nvme/slot-${JOB_SLOT}/dd
export COCOAPODS_CACHE_PATH=/Volumes/ci/nvme/slot-${JOB_SLOT}/pods
xcodebuild -scheme App -destination 'platform=iOS Simulator,name=iPhone 16' build

Бэкоф подчиняется таксономии ошибок: для линковки меньше попыток с большим интервалом, чтобы не бить стадом по горячему диску; для компиляции быстрая остановка освобождает слоты. Два порога глубины очереди хорошо работают: первый только режет параллелизм, второй открывает тикет на ёмкость до прихода счёта. Кэш CocoaPods разделяйте так же строго, как DerivedData: общий Pods-кэш кажется безобидным, пока несколько задач одновременно не переписывают манифесты и не забивают файловую систему мелкими синхронными записями.

4. Пять шагов от профилирования до тройной приёмки

  1. Профиль задач : разделите холодные инкременты, симулятор и Archive, измерьте доли очереди, компиляции, линковки и выгрузки. Если доля линковки растёт, смотрите общий DerivedData раньше закупки ядер.
  2. Контракты путей : зафиксируйте JOB_SLOT, self-hosted-метки и карту каталогов в шаблонах репозитория, запретите экспериментальным веткам писать в общие корни кеша, чтобы не утекали секреты.
  3. Ограничители параллелизма : глобально один-два Archive, для PR более высокие потолки с экспоненциальным бэкофом, матрицы симулятора на отдельную очередь без столкновения с пиками линковки на том же NVMe.
  4. Наблюдаемость : заведите глубину очереди, процент свободного диска и отношение минут ретраев в те же панели, что и кластеры падений, чтобы повторяющиеся таймауты линковки по умолчанию шли в инфраструктурные тикеты.
  5. Тройной прогон : возьмите коммит, прогоните три раза, сравните P95 и кластеры; если дисперсия остаётся, добавьте второй baseline с низкой конкуренцией раньше, чем грузить один узел до предела.

5. Три метрики для цитат в отчётах

Они удобны для резюме руководству, потому что переводят физику очередей в деньги без маскировки за зелёные индикаторы.

Если все три ухудшаются одновременно, это инцидент ёмкости даже при высоком проценте успеха: бюджет сгорает на инфраструктурном шуме, а не на продуктовых итерациях.

Эластичный роутинг решает, какие задачи уходят на хостинговые минуты, а какие остаются на bare-metal-метках. Тёплый путь настраивает поведение внутри каждого хоста. Эта статья про согласованность между хостами: шардирование делает параллелизм честным, аффинити стабилизирует инкременты, общий язык SLO выравнивает финансы и платформу. Без этого тройки документов команда обычно перескакивает с покупки одного Mac сразу к четырём, не заметив, что два узла с правильными путями дали бы больший выигрыш по P95, чем четыре узла с общим каталогом кеша.

7. FAQ

Вопрос: два узла — это пул? Ответ: да при контрактах и метриках, иначе два SSH с общей болью.

Вопрос: сначала схема или тесты? Ответ: смотрите, что доминирует — стампед или хвост очереди; Archive всегда отдельно.

Вопрос: сразу распределённый удалённый кеш? Ответ: обычно нет, пока не выровнены локальные разделы NVMe и пути на задачу; иначе растут вопросы консистентности и egress.

8. Выводы

Диспетчируемый пул превращает несколько Mac в программируемую ёмкость: шардирование определяет, настоящий ли параллелизм, аффинити — заслуживают ли доверия инкременты, метрики SLO — воспроизводимы ли обсуждения масштаба. Совместное чтение кривых очереди и диска переводит разбор с угадывания машины на объяснение параметров политики.

Полагаться только на общие хостинговые пулы значит держать раскладку диска и потолки параллелизма за вендорским забором, из-за чего macOS сложно воспринимать как полностью контролируемую территорию. Бессистемно накидать много узлов с маленькими дисками без шардов и аффинити — снова получить стампед линковки между Archive и pull request-ами, одновременно удлиняя хвосты и раздувая минуты ретраев. Команды, которым нужна устойчивая iOS-поставка и привычные SSH с launchd из мира Linux-VPS, обычно выигрывают, арендуя узлы Apple Silicon Mac cloud у VPSMAC, выделяя тяжёлые цепочки линковки на выделенные или малоконкурентные baseline и кодируя шарды плюс договорённости наблюдаемости в шаблонах пайплайна вместо одного общего корня DerivedData на все задачи.