最佳化疊代速度

回報問題 查看原始碼

本頁面說明如何在重複執行 Bazel 時最佳化 Bazel 的建構效能。

Bazel 的執行階段狀態

Bazel 叫用涉及數個互動部分。

  • bazel 指令列介面 (CLI) 是面向使用者的前端工具,可接收使用者的指令。

  • CLI 工具會針對每個不同的輸出基礎啟動 Bazel 伺服器。Bazel 伺服器通常是永久的,但會在閒置一段時間後關閉,以免資源浪費。

  • Bazel 伺服器會針對特定指令 (buildruncquery 等) 執行載入和分析步驟,並且在記憶體中建構建構圖的必要部分。產生的資料結構會保存在 Bazel 伺服器中,做為分析快取的一部分。

  • Bazel 伺服器也可以執行動作執行作業,或是在設定的情況下傳送動作的遠端執行。此外,系統也會在「動作快取」 (或稱為「執行快取」) 中快取動作執行作業的結果,這類快取可以是本機或遠端,而且可以在 Bazel 伺服器之間共用。

  • Bazel 叫用的結果會在輸出樹狀結構中提供。

反覆執行 Bazel

在一般的開發人員工作流程中,系統通常會以極高的頻率重複建構 (或執行) 一段程式碼,例如解決部分編譯錯誤或調查失敗的測試。在這種情況下,與基礎的重複動作 (例如叫用編譯器或執行測試) 相比,重複的叫用 bazel 必須盡可能減少負擔。

因此,我們會再查看 Bazel 的執行階段狀態:

分析快取是關鍵資料。大量時間可能只是在冷執行的載入與分析階段 (即是在 Bazel 伺服器啟動後執行,或捨棄分析快取時間所執行)。就單一成功的冷建構作業 (例如正式版) 而言,這筆費用是相當可觀的,但對於重複建立相同的目標而言,費用必須經過簡化,而且不會每次叫用時都重複計算。

分析快取相對容易失效。首先,它是 Bazel 伺服器處理中狀態的一部分,因此遺失伺服器會遺失快取。不過,快取也很容易失效,舉例來說,許多 bazel 指令列旗標會導致系統捨棄快取。這是因為許多旗標會影響建構圖表 (例如因為可設定的屬性) 造成影響。部分標記變更也可能會導致 Bazel 伺服器重新啟動 (例如變更啟動選項)。

良好的執行快取對建構效能也具有參考價值。執行作業快取可以在本機磁碟上儲存,也可以遠端保存。快取可在 Bazel 伺服器之間共用,而且可供開發人員共用。

避免捨棄分析快取

如果捨棄分析快取或伺服器已重新啟動,Bazel 就會列印警告。請避免在反覆使用中符合下列其中一項條件:

  • 請留意在疊代工作流程中變更 bazel 旗標的方式。舉例來說,搭配使用 bazel build -c optbazel cquery,會導致每個指令捨棄對方的分析快取。一般而言,請嘗試在特定工作流程期間使用一組固定的標記。

  • 遺失 Bazel 伺服器會失去分析快取。Bazel 伺服器有可設定的閒置時間,之後就會關閉。您可以視需求透過 bazelrc 檔案設定時間。當啟動標記變更時,伺服器也會重新啟動,所以同樣地,請盡量避免變更這些標記。

  • 請注意,如果您在 Bazel 執行期間反覆按下 Ctrl-C 鍵,就會終止 Bazel 伺服器。他們會中斷不再需要的執行中版本,試圖節省寶貴時間,但只要按下 Ctrl-C 鍵一次,就可要求結束當前叫用的寬限期。

  • 如果要使用同一工作區的多組標記,您可以使用多個不同的輸出數,並藉由 --output_base 標記切換。每個輸出集都會取得自己的 Bazel 伺服器。

如要將這項條件設為錯誤而非警告,您可以使用 --noallow_analysis_cache_discard 標記 (在 Bazel 6.4.0 中導入)