對遠端執行作業進行遠端快取命中偵錯

回報問題 查看來源

本頁說明如何在遠端執行作業中檢查快取命中率,以及如何調查快取失敗情形。

本頁面假設您已順利執行遠端執行作業的建構作業和/或測試,而且想確保自己有效使用遠端快取。

檢查快取命中率

在 Bazel 執行的標準輸出內容中,查看用來列出程序的 INFO 行,這大致與 Bazel 動作相對應。執行動作的那一行詳細資料。尋找 remote 標籤,標籤表示遠端執行的動作,linux-sandbox 代表在本機沙箱中執行的動作,以及其他執行策略的值。如果動作的結果來自遠端快取,會顯示為 remote cache hit

例如:

INFO: 11 processes: 6 remote cache hit, 3 internal, 2 remote.

在此範例中,有 6 次遠端快取命中,2 項動作沒有快取命中,且已從遠端執行。這 3 個內部部分可以忽略。通常是小型的內部動作 (例如建立符號連結)。本機快取命中不會納入這份摘要中。如果收到 0 個程序 (或數字低於預期),請依序執行 bazel clean 和建構/測試指令。

快取命中問題

如果快取未達到預期的快取命中率,請按照下列指示操作:

確保重新執行相同的建構/測試指令會產生快取命中

  1. 執行您要填入快取的建構作業和/或測試。首次在特定堆疊上執行新建構作業時,不會預期沒有遠端快取命中。做為遠端執行作業的一部分,動作結果會儲存在快取中,後續執行作業應會擷取這些結果。

  2. 執行 bazel clean。 這個指令會清除本機快取,防止結果遭到本機快取命中遮蓋。

  3. 在同一部機器上執行您要調查的建構和測試。

  4. 檢查 INFO 行中的快取命中率。如果沒看到 remote cache hitinternal 以外的程序,表示系統已正確填入您的快取並予以存取。在此情況下,請跳到下一節。

  5. 可能的不一致來源是建構作業中非本質的事情,導致動作在兩次執行作業中收到不同的動作金鑰。如要找到這些動作,請執行下列步驟:

    a. 重新執行有問題的建構作業或測試,取得執行記錄檔:

      bazel clean
      bazel --optional-flags build //your:target --execution_log_binary_file=/tmp/exec1.log
    

    b. 比較兩次執行作業之間的執行記錄。確保兩個記錄檔之間的動作都相同。 資料差異可讓您瞭解執行期間發生的變化。請更新您的版本,消除這些差異。

    如果您解決了快取問題,但現在重複執行會產生所有快取命中,請跳至下一部分。

    如果您的動作 ID 相同,但未在快取中找到了所需資料,則可能是設定中的某個項目阻止快取。請繼續進行本節,檢查是否有常見問題。

    如果您不需要差異比較執行記錄,可以改用使用者可理解的 --execution_log_json_file 旗標。因為這內含執行時間,而且不能保證排序,因此無法用於穩定的差異。

  6. 確認執行記錄中的所有動作都將 cacheable 設為 true。如果 cacheable 未出現在 ACTION 動作的執行記錄中,表示相應規則的定義在 BUILD 檔案中的定義包含 no-cache 標記。在執行記錄中查看使用者可理解的 progress_message 欄位,協助判斷動作來源。

  7. 如果動作相同且 cacheable,但沒有快取命中,可能是因為指令列中包含 --noremote_accept_cached,這會停用建構的快取查詢功能。

    如果很難確定實際的指令列,請使用 Build Event Protocol 中的標準指令列,如下所示:

    a. 將 --build_event_text_file=/tmp/bep.txt 加入 Bazel 指令,取得文字版本的記錄檔。

    b. 開啟文字版本的記錄檔,並使用 command_line_label: "canonical" 搜尋 structured_command_line 訊息。展開後的所有選項都會列出。

    c. 搜尋 remote_accept_cached,檢查是否已設為 false

    d. 如果 remote_accept_cachedfalse,請前往指令列或 bazelrc 檔案,確認目前設為 false 的位置。

確保跨機器快取

在同一部機器上按照預期情況在快取中找到了所需資料後,請在其他機器上執行相同的建構/測試。如果您懷疑機器上並沒有快取快取功能,請執行下列操作:

  1. 請微幅修改建構作業,以免影響現有的快取。

  2. 在第一部機器上執行建構:

     bazel clean
     bazel ... build ... --execution_log_binary_file=/tmp/exec1.log
    
  3. 在第二部機器上執行建構作業,確認已納入步驟 1 中的修改內容:

     bazel clean
     bazel ... build ... --execution_log_binary_file=/tmp/exec2.log
    
  4. 為這兩項執行作業比較執行記錄。如果記錄不相同,請調查建構設定是否有差異,以及從主機環境外洩到任一建構作業的屬性。

比較執行記錄檔

執行記錄包含建構期間執行的所有動作的記錄。每個動作都會有一個 SpawnExec 元素,當中包含動作金鑰的所有資訊,因此如果記錄相同,那麼動作快取金鑰就會是這樣。

如要比較兩個未如預期共用快取命中的記錄檔,請按照下列指示操作:

  1. 取得每個建構作業的執行記錄,並將其儲存為 /tmp/exec1.log/tmp/exec2.log

  2. 下載 Bazel 原始碼,並使用以下指令前往 Bazel 資料夾。需要原始碼,才能使用 execlog 剖析器剖析執行記錄。

    git clone https://github.com/bazelbuild/bazel.git
    cd bazel
    
  3. 使用執行記錄剖析器將記錄轉換為文字。下列叫用也會按照第一個記錄中的動作順序排序,以便進行比較。

    bazel build src/tools/execlog:parser
    bazel-bin/src/tools/execlog/parser \
      --log_path=/tmp/exec1.log \
      --log_path=/tmp/exec2.log \
      --output_path=/tmp/exec1.log.txt \
      --output_path=/tmp/exec2.log.txt
    
  4. 使用您最喜歡的文字與 /tmp/exec1.log.txt/tmp/exec2.log.txt 差異比較。