動態執行

回報問題 查看原始碼 Nightly · 8.0 . 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

動態執行是 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,請參閱上述說明),但可排除部分可能導致失敗的原因。