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

回報問題 查看來源

本頁面說明如何檢查快取命中率,以及如何在遠端執行環境中調查快取失敗的情況。

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

檢查快取命中率

在 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 相同,但沒有快取命中,表示設定中有內容阻止快取。請繼續執行本節,查看是否有常見問題。

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

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

    如果難以判斷實際指令列,請使用建構事件通訊協定中的標準指令列,如下所示:

    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 資料夾。需要透過原始碼使用 執行記錄檔剖析器剖析執行記錄檔。

    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 不同。