遠端快取

回報問題 查看原始碼 夜間 7.2 7.1 7.0 6.5 6.4

本頁面說明遠端快取、設定伺服器來代管快取,以及 進一步透過遠端快取執行建構作業

開發人員團隊和/或持續整合團隊使用遠端快取 (CI) 系統共用建構輸出內容。如果版本可以重現 可將一部機器的輸出內容安全地重複用於另一台機器 大幅加快建構速度

總覽

Bazel 會將建構作業拆解成多個獨立的步驟,這些步驟稱為動作。每個動作 包含輸入內容、輸出名稱、指令列和環境變數必要 系統會明確宣告每個動作的輸入和預期輸出內容

您可以將伺服器設為建構輸出內容的遠端快取, 每個動作輸出的內容這些輸出包含輸出檔案名稱清單和 雜湊值。透過遠端快取,您可以重複使用建構輸出內容 而非在本機建構新的輸出內容。

如要使用遠端快取,請按照下列步驟操作:

  • 將伺服器設為快取後端
  • 設定 Bazel 建構作業,以便使用遠端快取
  • 使用 Bazel 0.10.0 以上版本

遠端快取會儲存兩種類型的資料:

  • 動作快取,也就是動作雜湊與動作結果中繼資料的對應。
  • 輸出檔案的可定址儲存庫 (CAS)。

請注意,遠端快取會額外儲存每 1 秒的 stdout 和 stderr 動作。檢查 Bazel 的 stdout/stderr,因此並不是 預估快取命中次數

建構作業如何使用遠端快取

將伺服器設為遠端快取後,就能在多個 方式:

  • 讀取和寫入遠端快取
  • 讀取和/或寫入遠端快取 (特定目標除外)
  • 只能讀取遠端快取
  • 完全不使用遠端快取

執行可讀取和寫入遠端快取的 Bazel 建構作業時, 建構步驟如下:

  1. Bazel 會建立需要建構的目標圖表 列出必要動作的清單每個動作都有宣告的輸入內容 輸出檔案名稱
  2. Bazel 會檢查本機電腦中是否有現有建構輸出內容,並重複使用任何相關的 尋找找到的節點
  3. Bazel 會檢查快取中是否有現有建構輸出內容。如果找到輸出內容 Bazel 會擷取輸出內容。這屬於快取命中。
  4. 針對找不到輸出內容的必要動作,Bazel 會執行 並建立必要的建構輸出內容。
  5. 新的建構輸出內容會上傳至遠端快取。

將伺服器設為快取的後端

您必須設定伺服器,做為快取的後端。HTTP/1.1 伺服器可以將 Bazel 的資料視為不透明位元組,並將許多現有伺服器視為 可做為遠端快取後端Bazel 的 HTTP 快取通訊協定支援遠端程序 快取功能。

您必須負責選擇、設定及維護後端 儲存快取輸出內容選擇伺服器時,請考量下列幾點:

  • 網路速度。舉例來說,如果團隊在同一辦公室,您可以 執行自己的本機伺服器
  • 安全性。遠端快取存有您的二進位檔,因此必須安全無虞。
  • 輕鬆管理。例如 Google Cloud Storage 是全代管服務。

許多後端可用於遠端快取。部分選項 包括:

nginx

nginx 是開放原始碼的網路伺服器。[WebDAV 模組] 做為 Bazel 的遠端快取在 Debian 和 Ubuntu 上,您可以 nginx-extras 套件。在 macOS nginx 上可透過 Homebrew 取得:

brew tap denji/nginx
brew install nginx-full --with-webdav

以下是 nginx 的設定範例。請注意,您需要 將 /path/to/cache/dir 變更為 nginx 具備權限的有效目錄 讀取及讀取資料您可能需要將 client_max_body_size 選項變更為 較大的輸出檔案。伺服器需要其他 以及驗證等設定

nginx.confserver 區段的設定範例:

location /cache/ {
  # The path to the directory where nginx should store the cache contents.
  root /path/to/cache/dir;
  # Allow PUT
  dav_methods PUT;
  # Allow nginx to create the /ac and /cas subdirectories.
  create_full_put_path on;
  # The maximum size of a single file.
  client_max_body_size 1G;
  allow all;
}

bazel-remote

bazel-remote 是開放原始碼遠端建構快取,可用於 管理基礎架構已成功在實際工作環境中使用 。請注意,Bazel 專案 未針對 bazel-remote 提供技術支援。

這個快取會將內容儲存在磁碟中,並提供垃圾收集功能 強制執行儲存空間上限,並清除未使用的構件快取是 做為 [docker 映像檔],而其程式碼也可在 GitHub。 REST 和 gRPC 遠端快取 API 都受到支援。

參閱 GitHub 一文。

Google Cloud Storage

[Google Cloud Storage] 是全代管物件儲存空間 與 Bazel 遠端快取通訊協定相容的 HTTP API。它需要 擁有已啟用計費功能的 Google Cloud 帳戶。

如要使用 Cloud Storage 做為快取,請執行下列操作:

  1. 建立儲存空間值區。 務必選取離您最近的值區位置做為網路頻寬 對遠端快取來說很重要

  2. 為 Bazel 建立服務帳戶,以便向 Cloud Storage 進行驗證。詳情請見 建立服務帳戶

  3. 產生密鑰 JSON 金鑰並傳送至 Bazel 進行驗證。商店 因為任何取得金鑰的人都能讀取及寫入任意資料 讀取及寫入 GCS 值區

  4. 將下列標記新增至 Bazel 指令,即可連線至 Cloud Storage:

    • 使用標記將下列網址傳送至 Bazel: --remote_cache=https://storage.googleapis.com/bucket-name,其中 bucket-name 是儲存空間值區的名稱。
    • 使用 --google_credentials=/path/to/your/secret-key.json 旗標傳遞驗證金鑰,或是 --google_default_credentials,即可使用應用程式驗證
  5. 您可以設定 Cloud Storage 自動刪除舊檔案。操作方法請參閱 管理物件生命週期

其他伺服器

您可以設定任何支援 PUT 和 GET 做為快取的 HTTP/1.1 伺服器 後端。使用者表示,Hazelcast 等快取後端運作成功。 Apache httpdAWS S3

驗證

自 0.11.0 版起,HTTP 基本驗證的支援已新增至 Bazel。 您可以透過遠端快取網址,將使用者名稱和密碼傳送至 Bazel。 語法為 https://username:password@hostname.com:port/path請注意, HTTP 基本驗證會經由 因此必須一律與 HTTPS 搭配使用

HTTP 快取通訊協定

Bazel 支援透過 HTTP/1.1 進行遠端快取。這個通訊協定在概念上相當簡單: 二進位資料 (BLOB) 是透過 PUT 要求上傳,並透過 GET 要求下載。 動作結果中繼資料會儲存在路徑 /ac/ 中,且已儲存輸出檔案 路徑下 /cas/

舉例來說,假設有一個遠端快取在 http://localhost:8080/cache 下執行。 使用 SHA256 下載動作動作結果中繼資料的 Bazel 要求 雜湊 01ba4719... 看起來會像這樣:

GET /cache/ac/01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b HTTP/1.1
Host: localhost:8080
Accept: */*
Connection: Keep-Alive

一種 Bazel 要求,用於上傳具有 SHA256 雜湊 15e2b0d3... 的輸出檔案至 CAS 應如下所示:

PUT /cache/cas/15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225 HTTP/1.1
Host: localhost:8080
Accept: */*
Content-Length: 9
Connection: Keep-Alive

0x310x320x330x340x350x360x370x380x39

使用遠端快取執行 Bazel

將伺服器設為遠端快取後,如要使用遠端快取 將標記加入 Bazel 指令查看設定清單 下方的標記。

您可能也需要設定驗證程序,

建議您在 .bazelrc 檔案中新增這些旗標 因此每次執行 Bazel 時都必須指定這些變數。請依據您的專案和 您可以針對以下情況,為 .bazelrc 檔案新增標記:

  • 在本機電腦上
  • 在專案工作區中與團隊共用
  • 持續整合系統

讀取遠端快取及寫入資料

謹慎處理可以寫入遠端快取的人員。您可能會需要 只有您的持續整合系統才能寫入遠端快取。

使用以下標記讀取遠端快取並寫入資料:

build --remote_cache=http://your.host:port

除了 HTTP 之外,系統也支援以下通訊協定:HTTPSgrpcgrpcs

除了上述標記以外,還使用以下旗標僅讀取 遠端快取:

build --remote_upload_local_results=false

將特定目標從遠端快取中排除

如要從遠端快取中排除特定目標,請將目標標記為 no-cache。例如:

java_library(
    name = "target",
    tags = ["no-cache"],
)

從遠端快取中刪除內容

從遠端快取刪除內容是管理伺服器的一環。 從遠端快取中刪除內容的方式取決於您擁有的伺服器 設為快取刪除輸出時,您可以刪除整個快取 或刪除舊有輸出內容

快取輸出會儲存為一組名稱和雜湊值。刪除時 因此無法區分哪個輸出內容屬於特定用途 建構應用程式

建議您刪除快取中的內容,步驟如下:

  • 在快取中毒後建立乾淨的快取
  • 刪除舊有輸出內容,藉此減少儲存空間用量

Unix 通訊端

遠端 HTTP 快取支援透過 Unix 網域通訊端連線。行為 與 curl 的 --unix-socket 旗標類似。請使用以下指令設定 Unix 網域通訊端:

   build --remote_cache=http://your.host:port
   build --remote_cache_proxy=unix:/path/to/socket

Windows 不支援這項功能。

磁碟快取

Bazel 可以使用檔案系統中的目錄做為遠端快取。這是 在切換分支版本和/或工作時共用版本構件時相當實用 例如針對相同專案的多個工作區 個別進行結帳開始時間 Bazel 不會垃圾收集目錄,建議您自動執行 定期清理此目錄啟用磁碟快取,步驟如下:

build --disk_cache=path/to/build/cache

您可以使用 ~ 別名,將使用者特定路徑傳送至 --disk_cache 標記 (Bazel 會取代目前使用者的主目錄)。以備不時之需 透過專案的 已檢查 .bazelrc 個檔案。

已知問題

在建構期間修改檔案

如果在建構期間修改輸入檔案,Bazel 可能會上傳無效的檔案 遠端快取的結果。您可使用 --experimental_guard_against_concurrent_changes 旗標。有 未解決已知的問題,日後推出的版本將預設啟用這項功能。 請參閱 [問題 #3360] 瞭解最新資訊。一般來說,請避免在 建構應用程式

洩露至動作的環境變數

動作定義包含環境變數。這對於 跨電腦共享遠端快取命中舉例來說,含有 不同的 $PATH 變數不會共用快取命中。僅限環境變數 透過 --action_env 明確加入許可清單的項目包含在動作中 定義用於安裝 /etc/bazel.bazelrc 的 Bazel/Ubuntu 套件 並提供包括 $PATH 等環境變數許可清單如果您將 快取命中次數不如預期,請確認環境未包含舊的 /etc/bazel.bazelrc 檔案。

Bazel 不會追蹤工作區以外的工具

Bazel 目前不會追蹤工作區以外的工具。這可以是 舉例來說,如果動作使用 /usr/bin/ 的編譯器,就會發生問題。接著: 兩個使用者安裝不同編譯器後,在快取命中錯誤時會收到錯誤 因為輸出結果不同,但動作雜湊相同。詳情請見 問題 #4558 以取得更新項目。

在 Docker 容器中執行建構作業時,記憶體內漸進式狀態會遺失 即使在單個 Docker 容器中執行,Bazel 仍會使用伺服器/用戶端架構。 在伺服器端,Bazel 會維持記憶體內狀態,進而加快建構速度。 在 docker 容器 (例如 CI) 中執行建構作業時,會遺失記憶體內狀態 而 Bazel 必須在使用遠端快取前重新建構。