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

7.3 · 7.2 · 7.1 · 7.0 · 6.5

本頁說明如何檢查快取命中率,以及如何在遠端執行的情況下調查快取遺漏情形。

本頁面假設您有成功使用遠端執行功能的建構作業和/或測試,且您想確保有效使用遠端快取。

檢查快取命中率

在 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_compact_file=/tmp/exec1.log
    

    b. 比較兩次執行作業的執行記錄。確保兩個記錄檔之間的動作都相同。 差異可提供執行期間發生變更的線索。請更新建構項目,以消除這些差異。

    如果您能夠解決快取問題,且現在重複執行作業會產生所有快取命中,請跳至下一節。

    如果動作 ID 相同,但沒有快取命中,則表示設定中的某些內容會阻止快取。請繼續閱讀本節,檢查常見問題。

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

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

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

    a. 在 Bazel 指令中新增 --build_event_text_file=/tmp/bep.txt,即可取得文字版本的記錄檔。

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

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

    d. 如果 remote_accept_cachedfalse,請判斷 false 是在哪裡設定:指令列或 bazelrc 檔案。

確保跨機器快取

在同一部機器上按照預期情況在快取中找到了所需資料後,請在其他機器上執行相同的建構/測試。如果您懷疑系統未在多台機器上進行快取,請採取下列做法:

  1. 對建構項目進行小幅修改,避免命中現有的快取。

  2. 在第一台電腦上執行建構作業:

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

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

比較執行記錄檔

執行記錄包含建構期間的動作記錄。每筆記錄會說明輸入 (不僅檔案,還包含指令列引數、環境變數等) 與動作的輸出內容。因此,檢查記錄檔即可瞭解為何重新執行動作。

執行記錄可產生三種格式之一:精簡 (--execution_log_compact_file)、二進位 (--execution_log_binary_file) 或 JSON (--execution_log_json_file)。建議使用精簡格式,因為這類格式產生的檔案較小,且執行階段的額外負擔也較少。以下操作說明適用於任何格式。您也可以使用 //src/tools/execlog:converter 工具在兩者之間轉換。

如要比較兩個未如預期共用快取命中的版本的記錄,請執行下列操作:

  1. 從每個版本取得執行記錄,並儲存為 /tmp/exec1.log/tmp/exec2.log

  2. 下載 Bazel 原始碼,並建構 //src/tools/execlog:parser 工具:

    git clone https://github.com/bazelbuild/bazel.git cd bazel bazel build //src/tools/execlog:parser

  3. 使用 //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