Сравнительная таблица: sccache и ccache в общих пулах удалённого Mac
На один класс пайплайнов выбирайте один основной кеш компилятора. Смешение обёрток без изоляции переменных CC/CXX и каталогов быстро портит статистику и маскирует реальные промахи.
| Инструмент | Когда уместен | Трансграничный сценарий | Риски |
|---|---|---|---|
| sccache + Redis | Redis с TLS уже в контуре комплаенса; сборки Clang, Rust или MSVC-совместимые цепочки | Пространство ключей по продукту; сетевые задержки бьют по обёртке, а не по каждой записи объектного файла на NFS | Политика maxmemory и eviction должны совпадать с готовностью к пересборке; монорепозитории дают всплески горячих ключей |
| sccache + S3 (опционально) | Юристы предпочитают объектное хранилище Redis-памяти, доступны подписанные URL | Географически шардированные бакеты; настраивайте параллелизм запросов на раннер | Мелкие PUT и листинги могут съедать бюджет; локальный SCCACHE_DIR на NVMe обязателен |
| ccache + локальный APFS | Выделенные однотенантные хосты, большой CCACHE_DIR на внутреннем SSD |
Трансграничность косвенная: выигрыш, если раннер рядом с командой и без «длинного» NFS | Эфемерный диск сбрасывает тепло кеша без стадии восстановления из артефактов |
| ccache + NFS / HTTP secondary | Однородные Clang-сборки; сторедж уже отдаёт POSIX или HTTP-кеш в одном регионе | Межстрановые попадания работают только при низкой задержке к filer; иначе RTT метаданных доминирует | Нужны выверенные опции монтирования, локальный CCACHE_TEMPDIR, реалистичный CCACHE_MAXSIZE |
Ни один кеш не заменяет дисциплину закрепления тулчейна: обновление Xcode или драйвера Swift меняет отпечатки препроцессора — относитесь к доле попаданий как к сигналу, привязанному к матрице компиляторов, а не к «красивому проценту» ради отчёта.
Чеклист параметров: Redis, префиксы, NFS, параллелизм воркеров
Гигиена Redis для sccache: указывайте SCCACHE_REDIS_ENDPOINT с rediss://, если TLS завершается на брокере; выносите секреты в SCCACHE_REDIS_USERNAME и SCCACHE_REDIS_PASSWORD, не вшивайте их в URL. Ограничьте ACL одним индексом SCCACHE_REDIS_DB. Зафиксируйте в runbook таймауты клиента и tcp-keepalive, чтобы авторы CI понимали «зависшие» обёртки. Префикс логического пространства ключей — SCCACHE_REDIS_KEY_PREFIX (и при нескольких бэкендах — SCCACHE_NAMESPACE), чтобы эксперименты приложения не пересекались с драйверным ядром.
NFS для ccache: монтируйте с noatime, согласуйте rsize/wsize с вендором filer; не обещайте SLA по океану без микробенчмарка компиляции. CCACHE_TEMPDIR всегда на внутреннем SSD job — временные объекты не должны попадать на сетевой том.
Типовой пример для macOS-клиента (замените адрес и путь): mount -t nfs -o vers=4,rw,noatime,hard,intr,resvport filer01.internal:/export/ccache-shared /Volumes/ccache-nfs — затем export CCACHE_DIR="/Volumes/ccache-nfs/job-${CI_JOB_ID}" и отдельный подкаталог на job снижает вероятность скрытых гонок между пайплайнами на одном хосте. Для крайних случаев задержек метаданных рассмотрите локальный «горячий» CCACHE_DIR с периодической синхронизацией в enterprise NAS по расписанию, а не прямую запись тысяч мелких файлов через высокий RTT.
Параллельные воркеры: свяжите CMAKE_BUILD_PARALLEL_LEVEL или ninja -j с RAM; каждый линкер повышает пик RSS и может «голодать» обёртку при записи в Redis. На общих удалённых Mac начните с половины производительных ядер и масштабируйте, наблюдая счётчики ошибок в sccache --show-stats.
- В runbook закреплены канонический хост Redis, порт, индекс БД, имя ACL и процедура ротации пароля.
SCCACHE_REDIS_KEY_PREFIX(и при необходимостиSCCACHE_NAMESPACE) кодируют продукт, мажорный поток Xcode и поколение намеренного разрыва совместимости.- Пути
SCCACHE_DIRиCCACHE_DIRне пересекаются между тенантами без отдельных подкаталогов. - Экспорт NFS совместим с политикой снимков и резервного копирования; известен владелец очистки зависших блокировок.
- После фазы компиляции в лог попадают
sccache --show-statsилиccache -s. - Есть пороги свободного места для локального staging обёртки и для общего тома, с алертами до обрыва линковки.
Переменные окружения, каталоги кеша, таймауты и пороги повторов
Скопируйте блок под ваш стек и подставьте реальные имена хостов. Секреты — только из vault; в логи попадают идентификаторы без паролей.
# --- sccache + Redis (TLS; секреты отдельными переменными) ---
export SCCACHE_REDIS_ENDPOINT="rediss://sccache-redis.internal:6379"
export SCCACHE_REDIS_USERNAME="ci-sccache"
export SCCACHE_REDIS_PASSWORD="${SCCACHE_REDIS_PASSWORD_SECRET}"
export SCCACHE_REDIS_DB="0"
export SCCACHE_REDIS_KEY_PREFIX="acme/mobile/xcode-16-3/"
export SCCACHE_REDIS_EXPIRATION="2592000"
export SCCACHE_NAMESPACE="acme-ci"
export SCCACHE_DIR="${CI_PROJECT_DIR}/.sccache-staging"
export SCCACHE_IDLE_TIMEOUT="1800"
export SCCACHE_CACHE_SIZE="64G"
export RUSTC_WRAPPER="$(command -v sccache)"
export CARGO_BUILD_RUSTC_WRAPPER="${RUSTC_WRAPPER}"
export CMAKE_C_COMPILER_LAUNCHER="$(command -v sccache)"
export CMAKE_CXX_COMPILER_LAUNCHER="$(command -v sccache)"
mkdir -p "${SCCACHE_DIR}"
# --- ccache + APFS (локально на job) + лимит размера ---
export CCACHE_DIR="${CI_PROJECT_DIR}/.ccache"
export CCACHE_TEMPDIR="${TMPDIR:-/tmp}/ccache-${CI_JOB_ID:-local}"
export CCACHE_MAXSIZE="32G"
export CCACHE_LIMIT_MULTIPLE="0.85"
export CCACHE_COMPRESS="1"
export CCACHE_COMPRESSLEVEL="6"
export CCACHE_SLOPPINESS="pch_defines,time_macros"
export CMAKE_C_COMPILER_LAUNCHER="$(command -v ccache)"
export CMAKE_CXX_COMPILER_LAUNCHER="$(command -v ccache)"
mkdir -p "${CCACHE_DIR}" "${CCACHE_TEMPDIR}"
# --- Лестница повторов при сбоях транспорта обёртки ---
run_with_cache_retries() {
local attempt=1 max=4 delay=2
while [ "${attempt}" -le "${max}" ]; do
echo "compile phase attempt ${attempt}/${max}"
if "$@"; then return 0; fi
sleep "${delay}"
delay=$((delay * 2))
attempt=$((attempt + 1))
done
return 1
}
# Пример: run_with_cache_retries cmake --build build --parallel "${CMAKE_BUILD_PARALLEL_LEVEL:-8}"
Таймауты: выровняйте клиентские таймауты Redis с самой долгой ожидаемой LTO-единицей: если обрыв каждые девять минут, а линковка двенадцать, важнее поднять SCCACHE_IDLE_TIMEOUT, чем слепо наращивать -j. Для HTTP secondary в ccache 4.x начните с дефолтов вендора по connect/read и проверьте холодную сборку из каждого региона.
Пороги повторов: до четырёх попыток с паузами 2 с, 4 с, 8 с (экспоненциально); после исчерпания — падение job и полный дамп sccache --show-stats на последней попытке. Так вы отделяете кратковременный сетевой шум от деградации Redis или перегруженного filer.
FAQ
Заменяет ли sccache distcc? Нет: sccache хранит результаты компиляции, а не планирует удалённые фермы. Здесь фокус — экономика попаданий в кеш, а не топология распределённой компиляции.
Стоит ли включать все флаги ccache «sloppiness» ради процентов? Только те, что одобрены в вашей модели воспроизводимости; фиксируйте набор рядом с политикой SBOM.
Что делать, если Redis вытесняет горячие записи середины спринта? Считайте eviction нормой; расширяйте пространство имён только намеренно и планируйте ночной прогрев топ-таргетов.
Где в пайплайне Xcode DerivedData? Это другой слой; для полного iOS-контура см. матрицу DerivedData и прогрева на Mac CI.
Почему после обновления компилятора «внезапно» выросло число промахов? Меняются пути к заголовкам, макросы по умолчанию и версии стандартной библиотеки — это ожидаемо. Зафиксируйте в CI явный список поддерживаемых пар (Xcode × SDK × deployment target) и сбрасывайте префикс Redis или отдельный подкаталог ccache при мажорных переходах, иначе смешаются несовместимые объекты.
Стоит ли поднимать SCCACHE_CACHE_SIZE без лимита на общем раннере? Нет: локальный staging должен укладываться в квоту диска арендатора; сочетайте с алертами по свободному месту и политикой очистки между job, если оркестратор не гарантирует изолированный workspace.
Итог
sccache с Redis выигрывает, когда трансграничные раннеры должны делить одно управляемое пространство объектов; ccache на APFS с опциональным NFS или HTTP secondary сильнее, если комплаенс «про POSIX» и задержка к filer предсказуемо низкая. Зафиксируйте префиксы ключей, idle-таймауты и лестницу повторов рядом с матрицей компиляторов — тогда просадка попаданий читается как инцидент инфраструктуры, а не «магический флейк».
Когда понадобится выделить узлы Apple Silicon рядом с вашим кеш-слоем, откройте без регистрации страницы тарифов, покупки и аренды и центра помощи на macpull.com, сравните планы по числу параллельных job и объёму SSD под SCCACHE_DIR/CCACHE_DIR, затем вернитесь в блог за соседними матрицами по registry и сборочным пулам.
Если удобнее начать с международной витрины на английском, загляните на главную macpull.com (EN) — навигация к ценам и оформлению заказа так же не требует входа.