DevOps 2026-04-02 8 分

2026年 グローバルチームの iOS ビルドキャッシュ統制:Xcode Derived Data と依存キャッシュは単一リージョンに集約すべきか、各リージョンの物理 Mac にローカル化すべきか?

グローバルな iOS チームは「1 つの権威キャッシュ+越境同期」と「リージョンごとの物理 Mac 上のローカルキャッシュ」の間で揺れがちです。本記事ではレイテンシ・一貫性・コストを承認可能な閾値に揃え、2 つの意思決定マトリクス、7 ステップの Runbook、コピペ可能な rsync と環境変数、FAQ をまとめます。

2026年 グローバル iOS ビルドキャッシュ統制と Xcode Derived Data のリージョン戦略

誰が・何に困るか: グローバルチームが CI とリモート物理 Mac 越しに Xcode Derived Data や SPM/CocoaPods キャッシュを再利用すると、越境のキャッシュ取得で P95 ビルド時間が膨らみ、キャッシュのズレが散発的なリンクエラーを招きます。結論の芯: 低回転の読み取り専用依存キャッシュと、高回転の Derived Data を同じレプリケーション方針に束ねないでください。閾値マトリクスで単一リージョン権威かリージョン別コロケーションかを選びます。本記事で得られるもの: 表 2 枚、展開 7 ステップ、コピペコマンド、FAQ です。

1. ペインポイント

  1. 隠れコストは「小ファイルストーム」: Derived Data は大量の小ファイルとインデックスを含みます。越境 rsync やオブジェクト一覧のメタデータが実効スループットを食い、ジョブがコンパイルより「キャッシュ復元」で滞留します。
  2. 一貫性が「最新」より先: Xcode パッチ版、Swift ツールチェーン、モジュールキャッシュ、インデックスを混在させると増分ビルドが不安定になります。監査可能なコンテンツアドレスキーが必要で、「昨夜のビルド」という曖昧さは危険です。越境 RTT のベースラインは 2026年 マルチリージョンのリモート物理 Mac 受入:RTT/ジッター/パケット損失 SLO のマトリクス、協業レイテンシの打ち手は 2026年 グローバル共同開発遅延最適化ガイド(多拠点 Mac mini) を参照してください。
  3. 権限とコンプライアンス: 単一リージョン集中はソース指紋とビルド成果物を同一バケットに寄せがちです。リージョン別物理 Mac では、どのディレクトリが管轄外に出てよいか、監査済みローカルディスクに留めるべきかを定義し、中間バイナリを監査連鎖なしで共有に流さないでください。

2. Derived Data と依存キャッシュ:単一リージョン権威 vs リージョン別物理 Mac

下表はまず 各リージョンでビルドが独立して走るかジョブ時間のうちキャッシュ復元が占める割合(リポジトリ規模に応じて調整するオーダー感の閾値)で切ります。

観点 単一リージョン権威+非同期レプリケーション リージョン別物理 Mac ローカルキャッシュ(コロケーション)
最適な場面 主ビルドが 1 リージョン、その他は 1 日 < 3 本で 15〜45 分のコールドスタート許容 各リージョンで統合/フルビルドが 1 日 ≥ 5 本、またはキャッシュ復元がジョブ時間の約 25% 超
ネットワーク前提 専用線または同一クラウドバックボーン。越境バルクコピーはメンテ窓 ビルダーは Git・成果物と同リージョン。Derived Data は越境ホットパスに置かない
Derived Data 他リージョンが引く「ゴールデン」スナップショット。Xcode 完全一致でバケット分割 リージョンごとに独立した書き込みディレクトリ。パッチ版またぎのハードリンク再利用禁止
SPM/CocoaPods オブジェクトストレージ+CDN 読み取り専用。Derived Data から切り離す リージョンボリュームマウントまたはローカル SSD。上流レジストリと定期的にチェックサム突合
主なリスク 不良スナップショットが全リージョンに波及、越境帯域コスト急増 ディスクレイアウトと保持ポリシーがリージョンごとにドリフト。退避を自動化

3. 越境協業:レイテンシ×一貫性の意思決定マトリクス

Git と成果物の RTT を縦軸、キャッシュ起因インシデント率(週あたりキャッシュ帰属の非決定性失敗 ÷ 総ビルド数)を横軸にプロットすると、レビュー会議が速くなります。

キャッシュ起因 < 0.5% キャッシュ起因 ≥ 0.5%
リージョンから Git まで P95 RTT < 80 ms コロケーション 優先:ローカル Derived Data+同一リージョンの依存キャッシュ 先に キー空間 を直す:Xcode 版とブランチでバケット分割、その後コロケーション
P95 RTT ≥ 80 ms または間欠損失 単一リージョン権威 の依存キャッシュ+リージョン外はコンパイルクリティカル最小限のみ許容 越境の Derived Data ホット同期は 禁止。カナリアのクリーンビルドへ切替

SLO 文書に追記する例:現行リリーストレイン内のキャッシュエントリ最大経過時間。キャッシュ復元完了から初回 xcodebuild コンパイル開始までの P95 が中規模リポで 90 秒以内、モノレポで 180 秒以内。違反時は当該ジョブラベルのリモートキャッシュを無効化しリージョン内クリーンビルドを強制。

4. 7 ステップ Runbook

  1. パス棚卸し: DerivedData、SPM グローバルキャッシュ、CocoaPods キャッシュ、独自バイナリフレームワークを分離。コンテンツアドレスの読み取り専用ツリーのみオブジェクトストレージへ。リモート Mac での配布パイプライン全体は リモート Mac mini で iOS アプリをビルド・配布する完全ガイド (2026年版) も参照。
  2. キャッシュキー定義: 少なくとも Xcode 版、Swift 版、ブランチまたはロックファイルハッシュ、構成(Debug/Release)を含める。リポジトリ全体の単一 latest ポインタは禁止。
  3. 主ビルドリージョンの選定: メイン Git リモートと成果物レジストリに合わせる。他リージョンは依存層のみ同期するか、長いコールドスタートを受け入れる。
  4. カナリアジョブ: 1 台の物理 Mac がクリーンフルビルドとテストを通過するまで、新キャッシュバケットは昇格しない。
  5. 3 フェーズ計測: 復元・コンパイル・テストを個別に計装。復元が支配的なら CPU 増設よりトポロジーを直す。
  6. 無効化: Xcode アップグレード日に旧バケットを自動退役。N−1 の読み取り専用スナップショットはロールバック用に 7〜14 日保持。
  7. 承認アーティファクト: 2 つのマトリクスを 1 枚に印刷しオンコール Runbook の表紙に。キャッシュトポロジー変更のたびに、上記ペインポイントのマルチリージョン受入記事の RTT/ジッター検査を再実行。

5. コピペ用同期パラメータチェックリスト

ホストとパスを置換してスクリプトに貼り付けてください。削除系は必ずドライランを先に。

A. rsync:Derived Data バルク同期(タイムスタンプ保持。 --delete 系は慎重に)

リージョンボリュームへプッシュ(例):

rsync -aH --numeric-ids --delete-delay \
  --exclude 'ModuleCache.noindex/**' \
  --exclude 'CompilationCache.noindex/**' \
  --timeout=300 --contimeout=60 \
  ~/Library/Developer/Xcode/DerivedData/ \
  build@REGION-MAC.CORP:/Volumes/BuildCache/DerivedData/

B. rsync:SPM 読み取り専用キャッシュ(同時ビルダーのファイルを消さないよう --delete は省略)

rsync -aH --numeric-ids --omit-dir-times \
  ~/Library/Caches/org.swift.swiftpm/ \
  s3proxy-local:/spm-ro/KEY/

C. CocoaPods キャッシュの tarball ストリーム(越境帯域が高いとき、数時間の古さは許容)

tar --posix -cf - -C ~/Library/Caches/CocoaPods . \
  | pigz -1 \
  | ssh -o ServerAliveInterval=30 build@REMOTE 'pigz -d | tar -xf - -C /Volumes/Cache/CocoaPods'

D. 環境変数(CI テンプレ断片)

export DERIVED_DATA_PATH="/Volumes/BuildCache/DerivedData/${CACHE_KEY}"
export CLONED_SOURCE_PACKAGES_DIR_PATH="/Volumes/BuildCache/SPM/${CACHE_KEY}"
export COCOAPODS_CACHE_DIR="/Volumes/BuildCache/CocoaPods/${CACHE_KEY}"
# xcodebuild 前:書き込みパスと Xcode ビルドが CACHE_KEY と一致することを確認

6. まとめ

引用しやすい閾値(例): ① キャッシュ復元がジョブ時間の約 25% 超 → アーキレビュー。② キャッシュ関連失敗が週 0.5% 以上 → 越境 Derived Data 同期を凍結。③ ジョブあたり rsync タイムアウト 300 秒、接続タイムアウト 60 秒。④ キーに Xcode 完全一致を含める。⑤ カナリアクリーンビルド合格後のみプール全体昇格。

銀の弾はありません。依存キャッシュは「遠く・遅く・読み取り専用」Derived Data は「近く・速く・捨てられる」 が相性よいです。まずバケットを分離すれば、単一リージョンかマルチかは帯域の算術と SLO の数学に帰着します。

7. Mac mini でこの統制スタックを回す

上記のパスはすべて macOS でネイティブに動きます。Xcode、SwiftPM、ローカル SSD、Unix 系ツールを追加シムなしで揃えられます。Apple Silicon の Mac mini はユニファイドメモリの高帯域と、おおよそ 4 W 級のアイドル電力を両立し、フリートが止まっている間もインデックスと依存を温め続ける 24/7 のリージョンキャッシュアンカーに向きます。macOS のクラッシュ率は低く、Gatekeeper・SIP・FileVault は汎用ビルドホストと比べてセキュリティレビューと相性がよいです。

各地域で復元+コンパイルをローカル RTT 内に収め、Derived Data を tarball で大洋横断させたくないなら、リージョンごとに Mac mini プールを標準化するのが最も騒音の少ない形です。小型で、ファンレスまたは極めて静か、数年スパンでは電力と運用注意の総コストも抑えやすいです。

「どこかではビルドできる」から「SLO に署名できる」へ進むなら、標準化されたビルドノードの価格対安定性のアンカーとして Mac mini M4 は有力です。今日からリージョン別の物理 Mac 容量をレンタルまたは拡張し、実ディスクと実ネットワーク上にキャッシュ方針を着地させましょう。

8. FAQ

Derived Data は 1 リージョンに置くべきですか、各リージョンの物理 Mac に置くべきですか?

ビルドが主に 1 リージョンで、他は軽い検証のみなら単一権威と非同期レプリケーションで足ります。各リージョンで毎日フルビルドがあり、越境の Git や成果物 RTT が支配的なら、書き込み可能な Derived Data をリージョン別物理 Mac にコロケーションし、依存解決も同一リージョンに揃えます。

特に重要な一貫性の閾値は何ですか?

承認しやすい例:リリーストレイン内の最大キャッシュ経過時間、チェックサムまたはコンテンツキー一致、Xcode パッチ版をまたいだ Derived Data パス共有禁止、SPM resolve 失敗率、コールドスタート比率。閾値超過時は越境増分よりリージョン内クリーンビルドを優先。

SPM と CocoaPods は Derived Data と同じ方針が必須ですか?

いいえ。依存はコンテンツアドレスの読み取り専用ストレージ向き。Derived Data はビルド成果物とインデックスです。依存はオブジェクトストレージや共有読み取り専用ボリューム、Derived Data はリージョンごとの書き込み可能ストレージに分けます。

単一リージョン集中の最大のリスクは何ですか?

越境帯域、巨大ツリーの長尾レイテンシ、1 回の不良同期による複数リージョン汚染です。チャンク検証、ブランチ別バケット、昇格前カナリアで緩和します。

期間限定

マルチリージョンの物理 Mac で iOS ビルドを回していますか?

Git と成果物にノードを近接させ、Derived Data と依存の復元レイテンシを圧縮。Xcode ビルドプールとリモートデスクトップをオンデマンドで立ち上げられます。

従量課金 即時利用 安全・高信頼
macOSクラウドレンタル 期間限定特別価格
今すぐ購入