動態執行

動態執行是 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 剖析功能來查看一般快取命中需要多少時間。

動態執行可以搭配本機沙箱策略和永久工作站使用。與動態執行搭配使用時,永久工作站會自動以沙箱機制執行,且無法使用 Multix worker。在 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,請參閱上方說明),但會移除一些可能導致失敗的原因。