本頁說明如何檢查快取命中率,以及如何調查遠端執行環境中的快取未命中情況。
本頁面假設您已成功使用遠端執行功能建構及/或測試,並想確保有效運用遠端快取。
查看快取命中率
在 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
,然後執行建構/測試指令。
排解快取命中問題
如果快取命中率未達預期,請採取下列做法:
確認重新執行相同的建構/測試指令會產生快取命中
執行您預期會填入快取的建構和/或測試。在特定堆疊上首次執行新版本時,您預期不會有任何遠端快取命中。在遠端執行作業中,動作結果會儲存在快取中,後續執行作業時應會擷取這些結果。
執行
bazel clean
。 這項指令會清除本機快取,讓您調查遠端快取命中情形,而不必擔心結果遭到本機快取命中情形遮蓋。再次執行您正在調查的建構和測試 (在同一部電腦上)。
查看
INFO
行的快取命中率。如果除了remote cache hit
和internal
以外,沒有看到任何程序,表示快取正在正確填入及存取。如果沒有,請跳至下一節。造成差異的可能來源是建構中的非密封項目,導致動作在兩次執行中收到不同的動作金鑰。如要找出這些動作,請按照下列步驟操作:
a. 重新執行有問題的建構或測試,取得執行記錄:
bazel clean
bazel --optional-flags build //your:target --execution_log_compact_file=/tmp/exec1.log
b. 比較兩次執行的執行記錄。確認兩個記錄檔中的動作完全相同。 差異可提供線索,瞭解兩次執行之間發生的變化。請更新建構版本,消除這些差異。
如果快取問題已解決,且重複執行作業時,所有快取都命中,請跳至下一節。
如果動作 ID 相同,但沒有快取命中,表示設定中的某些項目會阻礙快取。請繼續閱讀本節,檢查常見問題。
確認執行記錄中的所有動作都已將
cacheable
設為 true。如果特定動作的執行記錄中未顯示cacheable
,表示對應規則的定義可能在BUILD
檔案中含有no-cache
標記。查看執行記錄中的mnemonic
和target_label
欄位,有助於判斷動作的來源。如果動作相同且
cacheable
,但沒有快取命中,則可能是因為指令列包含--noremote_accept_cached
,這會停用建構的快取查閱。如果難以找出實際的指令列,請使用 Build Event Protocol 中的標準指令列,如下所示:
a. 在 Bazel 指令中新增
--build_event_text_file=/tmp/bep.txt
,即可取得文字版本的記錄檔。b. 開啟文字版本的記錄檔,搜尋
structured_command_line
訊息中的command_line_label: "canonical"
。展開後會列出所有選項。c. 搜尋「
remote_accept_cached
」,並確認是否已設為「false
」。d. 如果
remote_accept_cached
為false
,請判斷false
的設定位置:指令列或 bazelrc 檔案。
確保跨機器的快取
在同一部機器上,快取命中次數如預期發生後,請在另一部機器上執行相同的建構/測試作業。如果懷疑快取未在電腦間發生,請採取下列做法:
稍微修改建構內容,避免命中現有快取。
在第一部電腦上執行建構作業:
bazel clean
bazel ... build ... --execution_log_compact_file=/tmp/exec1.log
在第二部電腦上執行建構作業,確保包含步驟 1 的修改內容:
bazel clean
bazel ... build ... --execution_log_compact_file=/tmp/exec2.log
比較這兩次執行的記錄。如果記錄不相同,請調查建構設定是否有差異,以及主機環境的屬性是否洩漏到任一建構中。
比較執行記錄
執行記錄包含建構期間執行的動作記錄。 每筆記錄都會說明動作的輸入內容 (不只是檔案,還包括指令列引數、環境變數等) 和輸出內容。因此,檢查記錄檔可以找出動作重新執行的原因。
執行記錄可採用三種格式之一:精簡 (--execution_log_compact_file
)、二進位 (--execution_log_binary_file
) 或 JSON (--execution_log_json_file
)。建議使用精簡格式,因為這樣產生的檔案較小,且執行階段的額外負擔極少。下列操作說明適用於任何格式。您也可以使用 //src/tools/execlog:converter
工具在兩者之間轉換。
如要比較兩個建構版本的記錄,但這兩個版本並未如預期共用快取命中,請按照下列步驟操作:
從每個建構作業取得執行記錄,並儲存為
/tmp/exec1.log
和/tmp/exec2.log
。下載 Bazel 原始碼並建構
//src/tools/execlog:parser
工具:git clone https://github.com/bazelbuild/bazel.git cd bazel bazel build //src/tools/execlog:parser
使用
//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
使用您喜愛的文字差異比較工具,比較
/tmp/exec1.log.txt
和/tmp/exec2.log.txt
。