動態執行是 Bazel 自 0.21 版起提供的功能,可同時啟動相同動作的本機和遠端執行作業,並使用第一個完成分支的輸出內容,取消其他分支。這項功能結合了遠端建構系統的執行效能和/或大型共用快取,以及本機執行作業的低延遲,提供兩者兼具的優點,無論是清理或增量建構作業皆適用。
本頁說明如何啟用、調整及偵錯動態執行作業。如果您已設定本機和遠端執行作業,並嘗試調整 Bazel 設定以提升效能,這篇文章正是您需要的參考資料。如果您尚未設定遠端執行功能,請先參閱 Bazel 的遠端執行功能總覽。
是否要啟用動態執行功能?
動態執行模組是 Bazel 的一部分,但要使用動態執行功能,您必須能夠透過相同的 Bazel 設定在本機和遠端編譯。
如要啟用動態執行模組,請將 --internal_spawn_scheduler
標記傳遞至 Bazel。這會新增名為 dynamic
的新執行策略。您現在可以將這項做法用於要動態執行的助憶法,例如 --strategy=Javac=dynamic
。如要瞭解如何選擇要啟用動態執行作業的助憶法,請參閱下一節。
對於使用動態策略的任何助憶法,系統會從 --dynamic_remote_strategy
旗標取得遠端執行策略,從 --dynamic_local_strategy
旗標取得本機策略。傳遞 --dynamic_local_strategy=worker,sandboxed
會為動態執行的本機分支設定預設值,以便依序嘗試使用 worker 或沙箱執行。傳遞 --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 版本起,效能分析剖析會收錄 worker 執行作業的相關資料,包括在輸掉動態執行競爭後,完成工作要求所花費的時間。如果您發現動態執行 worker 執行緒花費大量時間取得資源,或是在 async-worker-finish
中花費大量時間,則可能有某些緩慢的本機動作會延遲 worker 執行緒。
在上述使用 8 個 Javac 工作站的設定檔中,我們發現許多 Javac 工作站輸掉了競爭,並在 async-worker-finish
執行緒上完成工作。這是因為非 worker 助憶法占用足夠的資源,導致 worker 延遲。
當只有 Javac 搭配動態執行作業時,只有約一半的已啟動工作站在開始工作後會失去競爭。
先前建議使用的 --experimental_spawn_scheduler
旗標已淘汰。這會啟用動態執行功能,並將 dynamic
設為所有助憶符號的預設策略,這通常會導致這類問題。
疑難排解
動態執行的問題可能很難偵測,因為只有在本機和遠端執行的特定組合下才會出現。--debug_spawn_scheduler
會從動態執行系統新增額外輸出內容,協助您排除這些問題。您也可以調整 --local_execution_delay
標記和遠端與本機工作數量,以便更輕鬆地重現問題。
如果您在使用 standalone
策略執行動態動作時遇到問題,請嘗試在不使用 --experimental_local_lockfree_output
的情況下執行,或是在沙箱中執行本機動作。這可能會稍微減緩建構作業 (如果您使用 Mac 或 Windows,請參閱上述說明),但可排除部分可能導致失敗的原因。