建置佇列仍在等待,快取命中卻沒有明顯改善:先暫緩 Bazel 9 遠端快取的全量啟用,固定 Mac 工具鏈並做唯讀 A/B 試點,再用命中與排隊資料決定快取或擴充 Mac。

這篇文章適合已使用 Bazel 建置大型 iOS 專案、想降低重複編譯時間的研發效能負責人;也適合正在比較新增 Mac 節點、共享快取與遠端 Mac 的 IT、FinOps、安全及平台工程團隊。

最後更新於 2026 年 9 月 1 日;版本與工具鏈資料核實自 Bazel 官方遠端快取文件Bazel 版本發布紀錄rules_apple 官方儲存庫Apple Xcode 系統要求

先用收益條件判斷是否值得投入

Bazel 9 遠端快取值得上線的前提,不是「專案用了 Bazel」這一項,而是三件事同時成立:建置 action 可重現、不同 Mac 節點存在足夠的重複工作、快取連線與權限治理不會抵消復用收益。只要其中一項尚未證明,就不應直接讓所有工作流程讀寫共享快取。

你可以先按以下條件分支執行:

  • 相同提交在不同固定 Mac 節點上能產生一致 action 輸入,且重複建置明顯集中於可復用的編譯工作,先選唯讀遠端快取試點。
  • 快取命中不穩定,但主要等待來自 Mac 節點排隊、簽名或正式歸檔,優先擴充 Mac 建置容量。
  • 快取服務與 Mac 建置節點跨地域,下載耗時、傳輸失敗或等待抖動已接近重建成本,先把快取放到建置節點同地域,否則回退到本地快取或增加節點。
  • 簽名、模擬器測試、正式歸檔或敏感 Target 無法安全復用,把它們從共享快取範圍剔除,並把真實 Mac 容量列入預算。
  • 工具鏈仍在變動,或 Bazel 9、rules_apple、rules_swift、Xcode 與 SDK 的組合尚未由團隊驗證,只保留隔離試驗,不進入正式流水線。
遠端快取復用的是 Bazel action 的輸出,不是把 Xcode、iOS 模擬器或程式碼簽名搬到非 Mac 節點執行。它也不同於 Xcode 原生編譯快取:前者依賴 Bazel action 輸入與輸出的一致性,後者受 Xcode 建置設定及本機環境影響。遠端執行則是另一種架構,不能把三者混為同一項投資。

第一步:先量出真正需要解決的指標

不要從「開啟快取後單次建置快了多少」開始。你需要從企業 CI 日誌收集以下基線:

  • 重複建置比例:同一分支、相近提交或相同依賴圖中,哪些 action 在不同 Mac 節點反覆執行。
  • 乾淨建置頻率:清除本機輸出、節點重建、Xcode 或 SDK 更新後,多少工作會重新計算。
  • Mac 排隊等待:工作尚未取得 Mac 前的等待時間,是否比實際編譯更常成為瓶頸。
  • 跨節點任務重合度:不同節點是否使用相同 Bazel 設定、Xcode、SDK、rules_apple 與 rules_swift。
  • 未覆蓋工作量:簽名、歸檔、模擬器測試和外部工具執行在總流水線中所佔的比例。
Bazel 官方文件說明,遠端快取包含 action cache 與以內容位址識別的輸出物件;因此,只有 action 的輸入一致,快取結果才具有可復用條件。你應保存命中與未命中的 action 診斷,而不是只保存整體建置秒數。[官方快取協定與物件路徑說明](https://bazel.build/remote/caching) 可作為日誌欄位設計的依據。

**注意:** 快取命中不等於流水線完成。正式歸檔、簽名、模擬器啟動和測試執行仍可能必須在具備完整 Apple 工具鏈的 Mac 上進行。

先固定相容性,再判斷跨 Mac 是否可復用

Bazel 9 的版本標籤不能直接等同於生產可用。任一組合都應分成三種狀態:

  • 官方有明確支援:在 Bazel 發布紀錄、rules_apple 或 rules_swift 的官方資料中能找到相應說明。
  • 團隊已驗證:官方沒有阻擋,但你已用實際專案、固定 Xcode 與 SDK 完成產物和測試驗收。
  • 仍需隔離試驗:預發布版、開發分支、未合併修復或缺少一致性證據的組合。
截至本文核查日期,Bazel 9 的次版本與 rules_apple 的具體相容範圍仍應以[最新 Bazel Release Notes](https://github.com/bazelbuild/bazel/releases)及[rules_apple 官方支援資料](https://github.com/bazelbuild/rules_apple)為準;rules_swift 的工具鏈條件則要一併查看[官方 rules_swift 儲存庫](https://github.com/bazelbuild/rules_swift)。Apple 對 Xcode、macOS 與 SDK 的要求也會影響 Mac 節點是否能完成正式工作,不能只檢查 Bazel 版本。

跨 Mac 無法命中,通常來自以下邊界:

  1. 環境變數、工作目錄或絕對路徑被 action 間接讀取。
  2. 主機上的外部工具版本不同,或工具未被明確納入輸入。
  3. Xcode、SDK、Swift 編譯器或系統標頭漂移。
  4. 產物依賴未宣告的時間、主機名稱、使用者路徑或本機憑證。
  5. rules_apple、rules_swift 與 Bazel 升級後,action key 或輸出格式改變。
這些問題可能造成未命中,也可能造成更嚴重的錯誤復用。當你無法解釋某個 action 為何命中時,不應把它當作成功指標。若你正在整理 Bazel iOS 建置環境,也可先參考 [Bazel iOS 建置環境的版本驗收方向](https://macgpu.com/zh-Hant/m4-dinggou.html),再把已驗證的工具鏈版本鎖定到 CI 節點映像或重建文件中。

第二步:用傳輸與儲存資料驗證收益

試點至少要同時記錄遠端命中、下載耗時、上傳耗時、傳輸失敗、快取物件成長與冷啟動表現。每一項都要按提交、節點、工作類型和地域分組,避免把一個熱門 action 的命中誤認為整條 iOS CI 已經加速。

對照四種方案時,請分開看:

  • 遠端快取:適合復用已完成且輸入一致的 Bazel action,不能消除 Mac 執行需求。
  • 遠端執行:把部分 action 派往其他執行環境,會新增工具鏈、隔離、排程與合規問題。
  • Xcode 原生編譯快取:偏向 Xcode 建置流程內的本機復用,不能直接取代 Bazel 遠端快取治理。
  • 增加 Mac 節點:直接提升可執行容量,對排隊、簽名、歸檔和模擬器工作最有幫助,但會增加主機、維護與閒置成本。
同地域快取通常較容易先驗證,因為建置節點不必把大量輸出跨遠距離傳輸;跨地域則要把頻寬、出口費、TLS、失敗重試與遠端團隊連線品質納入模型。官方文件可協助你確認協定與命中排查方式,但不會替你的專案提供加速比例或成本結論;這些只能由企業日誌或本站實測得出。

如果團隊需要比較不同地域的遠端 Mac 作為基準節點,應把 MACGPU 的 Mac 節點地域選擇納入連線延遲、權限隔離與資料流向評估,而不是只比較單一建置時間。

第三步:把寫入權限和產物風險切開

共享快取最容易被低估的不是磁碟容量,而是誰可以寫入,以及錯誤產物如何被發現。建議採用以下權限分層:

  • 固定 CI 建置節點:工具鏈鎖定、可寫入指定命名空間,並保留提交、節點和執行者稽核紀錄。
  • 一般開發機與臨時節點:預設唯讀,只能取得已核准的非敏感輸出。
  • 簽名與正式歸檔節點:按 Target 分流;涉及憑證、金鑰或正式發布的工作,不應預設讀取或寫入共享快取。
  • 隔離試驗節點:可以讀寫測試命名空間,但不得與生產快取共用憑證或物件路徑。
你還需要驗收傳輸加密、身份憑證輪替、產物存取範圍、快取投毒處置、日誌中的路徑與環境變數遮罩,以及物件刪除和保留政策。若發現錯誤產物,應能立即撤銷寫入權限、隔離相關節點、刪除受影響物件並以無快取方式重建;沒有這套復原動作,就不適合擴大寫入範圍。

第四步:用 A/B 證據決定快取或 Mac 容量

採用同一提交、同一工具鏈與相同 Mac 配置,建立三組對照:

  1. 無快取:取得完整重建基線,記錄 action、整體建置、排隊和失敗資料。
  2. 唯讀快取:只允許取得既有輸出,觀察命中、下載與錯誤復用。
  3. 受控讀寫快取:只讓固定 CI 節點寫入,確認新增物件、後續命中與清除流程。
完成後使用以下決策清單:
  • 唯讀快取穩定命中,下載成本低於重建成本,且正式未覆蓋工作仍不是主要瓶頸,進入小範圍生產。
  • 命中集中在少數 action,整體排隊仍由 Mac 容量造成,保留快取並優先增加 Mac 節點。
  • 寫入後出現不可解釋差異、產物驗證失敗或日誌洩漏,停止讀寫,回到唯讀或無快取模式,完成修復後再測。
  • 跨地域傳輸失敗和下載等待抵消復用收益,改為同地域快取;若仍無法改善,停止快取投資並擴充 Mac。
  • 工具鏈升級導致大量 action 失效,先保留舊命名空間供回退,按照版本驗收結果決定是否清理,而不是每次升級都盲目清空全部物件。
TCO 模型應包含快取建設與儲存、網路與傳輸、稽核和運維工時、Mac 節點、排隊損失,以及快取不可用時的備援。不要預填節省比例:遠端快取只優化可復用 action,無法替你支付簽名、歸檔、模擬器和工具鏈驗證所需的真實 Mac 容量。

若你需要隔離的 Apple Silicon 基準節點或短期測試資源,可先查看 MACGPU 的遠端 Mac 方案;實際評估時仍應以你的地域、連線方式、週期和安全要求核對,不要把租用節點直接當作快取命中保證。

第五步:安排失效與升級演練

正式准入前,至少要演練快取服務不可用、錯誤產物、寫入節點遭撤銷、Mac 節點重建和工具鏈回退。每次演練都應留下觸發條件、偵測方式、責任人、復原時間及是否需要重新簽名的紀錄。

升級 Bazel 9 次版本、rules_apple、rules_swift、Xcode 或 SDK 時,先在隔離命名空間重跑同一組 A/B 測試。只有當產物驗證、測試結果、命中診斷和回退流程都通過,才把新組合列入官方支援或團隊已驗證清單。

常見企業決策問題

FAQ 中的答案不能取代你的建置日誌。尤其是加速比例、快取容量與成本,必須以相同提交和相同 Mac 配置的實際紀錄計算。

結語:先用證據換容量,而不是用快取猜容量

如果你的 iOS CI 已有可重現 action、固定的 Apple 工具鏈和穩定的同地域連線,Bazel 9 遠端快取值得以唯讀方式試點;如果主要瓶頸是簽名、歸檔、模擬器或 Mac 排隊,增加建置節點會比擴大快取更直接。現有方案若依賴開發機各自維護環境,容易出現工具鏈漂移、權限難以稽核與峰值容量不足;若只依靠快取,又會在快取失效時暴露真實 Mac 容量缺口。

完成 A/B 驗收後,你可以把峰值排隊、簽名工作和未命中 action 換算成節點需求。若現有環境無法提供隔離試驗或短期峰值資源,再評估透過 MACGPU 按週期啟用遠端 Mac 作為基準節點或彈性建置池;這比在沒有命中、傳輸與恢復證據前,直接長期採購硬體更容易控制風險。