動態執行是 Bazel 0.21 版之後的功能,可平行啟動相同動作的本機和遠端執行作業,並使用第一個完成的分支機構輸出內容,取消其他分支機構。這項功能結合了遠端建構系統的執行能力和/或大型共用快取,以及本機執行的低延遲特性,可為乾淨和累加建構作業提供兩全其美的解決方案。
本頁說明如何啟用、調整及偵錯動態執行。如果您已設定本機和遠端執行,並嘗試調整 Bazel 設定以提升效能,這份頁面將對您有所幫助。如果您尚未設定遠端執行,請先前往 Bazel Remote Execution 總覽。
是否啟用動態執行?
動態執行模組是 Bazel 的一部分,但如要使用動態執行,您必須已能從相同的 Bazel 設定在本機和遠端進行編譯。
如要啟用動態執行模組,請將 --internal_spawn_scheduler
標記傳遞至 Bazel。這會新增名為 dynamic
的新執行策略。現在可以將這項功能做為動態執行的助記符策略,例如 --strategy=Javac=dynamic
。如要瞭解如何選擇啟用動態執行的助記符,請參閱下一節。
如果是使用動態策略的任何助記符,遠端執行策略會取自 --dynamic_remote_strategy
旗標,本機策略則取自 --dynamic_local_strategy
旗標。傳遞 --dynamic_local_strategy=worker,sandboxed
會將動態執行的本機分支預設為依序嘗試使用工作站或沙箱執行。傳遞 --dynamic_local_strategy=Javac=worker
只會覆寫 Javac 助記符的預設值。遠端版本也是如此。這兩個標記都可以多次指定。如果動作無法在本機執行,系統會照常遠端執行,反之亦然。
如果遠端系統有快取,--local_execution_delay
旗標會在遠端系統指出快取命中後,將延遲時間 (以毫秒為單位) 新增至本機執行作業。這樣一來,當快取命中率較高時,就不會執行本機執行作業。預設值為 1000 毫秒,但應調整為比快取命中通常所需時間稍長。實際時間取決於遠端系統和往返時間。通常,特定遠端系統的所有使用者都會有相同的值,除非部分使用者距離夠遠,導致來回延遲。您可以使用 Bazel 剖析功能,查看一般快取命中所需的時間。
動態執行可搭配本機沙箱策略和持續性工作人員使用。搭配動態執行使用時,持續性工作站會自動透過沙箱執行,且無法使用多工工作站。在 Darwin 和 Windows 系統上,沙箱策略可能會很慢;您可以傳遞 --reuse_sandbox_directories
,減少在這些系統上建立沙箱的額外負荷。
動態執行也可以搭配 standalone
策略執行,但由於 standalone
策略必須在開始執行時取得輸出鎖定,因此會有效阻止遠端策略先完成。--experimental_local_lockfree_output
旗標可讓本機執行作業直接寫入輸出內容,但如果遠端執行作業先完成,就會中止本機執行作業,藉此解決這個問題。
如果動態執行的其中一個分支先完成,但失敗了,整個動作就會失敗。這是刻意選擇,可避免本地和遠端執行之間的差異遭到忽略。
如要進一步瞭解動態執行及其鎖定機制,請參閱 Julio Merino 的精彩網誌文章
何時該使用動態執行?
動態執行需要某種形式的遠端執行系統。目前無法使用僅限快取的遠端系統,因為快取未命中會視為失敗的動作。
並非所有類型的動作都適合遠端執行。最適合的候選項目是本質上在本機執行速度較快的項目 (例如使用持續性工作人員),或是執行速度夠快,以致於遠端執行作業的負擔會佔據執行時間的項目。由於每個在本機執行的動作都會鎖定一定數量的 CPU 和記憶體資源,因此執行不屬於這些類別的動作只會延遲執行屬於這些類別的動作。
自版本 5.0.0-pre.20210708.4 起,效能剖析會包含有關工作人員執行的資料,包括在動態執行競賽中落敗後,完成工作要求所花費的時間。如果發現動態執行工作者執行緒花費大量時間取得資源,或在 async-worker-finish
中耗費大量時間,可能表示有某些緩慢的本機動作延遲了工作者執行緒。
在上述使用 8 個 Javac 工作站的設定檔中,我們看到許多 Javac 工作站輸掉競爭,並在 async-worker-finish
執行緒上完成工作。這是因為非工作站助記符占用的資源足夠,導致工作站延遲。
如果只使用動態執行功能執行 Javac,開始工作後,只有大約一半的工作站會輸掉競賽。
先前建議使用的 --experimental_spawn_scheduler
旗標已淘汰。這會啟用動態執行,並將 dynamic
設為所有助記符的預設策略,這通常會導致這類問題。
疑難排解
動態執行的問題可能很細微,難以偵錯,因為這些問題可能只會在特定本機和遠端執行組合中顯現。--debug_spawn_scheduler
會從動態執行系統新增額外輸出內容,有助於偵錯這些問題。您也可以調整 --local_execution_delay
旗標和遠端與本機作業的數量,以便重現問題。
如果使用 standalone
策略時動態執行發生問題,請嘗試不使用 --experimental_local_lockfree_output
執行,或在沙箱中執行本機動作。這可能會稍微減緩建構速度 (如果您使用 Mac 或 Windows,請參閱上文),但可排除一些可能導致失敗的原因。