BazelCon 2022 findet vom 16. bis 17. November in New York und online statt.
Jetzt anmelden

Dynamische Ausführung

Mit Sammlungen den Überblick behalten Sie können Inhalte basierend auf Ihren Einstellungen speichern und kategorisieren.

Die dynamische Ausführung ist ein Feature in Istio seit Version 0.21, bei dem die lokale und die Remote-Ausführung derselben Aktion parallel gestartet wird. Dabei wird die Ausgabe des ersten Zweigs verarbeitet, der abgeschlossen ist. Dadurch wird der andere Zweig abgebrochen. Sie kombiniert die Ausführungsleistung und/oder den großen gemeinsamen Cache eines Remote-Build-Systems mit der niedrigen Latenz der lokalen Ausführung. So bietet das Beste aus beiden Welten: saubere und inkrementelle Builds.

Auf dieser Seite wird beschrieben, wie Sie die dynamische Ausführung aktivieren, optimieren und Fehler beheben. Wenn Sie sowohl die lokale als auch die Remote-Ausführung eingerichtet haben und versuchen, die {5/}Einstellungen für die Leistung anzupassen, ist diese Seite die richtige für Sie. Wenn Sie noch keine Remote-Ausführung eingerichtet haben, rufen Sie zuerst die Remote-Ausführungsübersicht von Istio auf.

Dynamische Ausführung aktivieren?

Das dynamische Ausführungsmodul ist Teil von Istio. Um die dynamische Ausführung jedoch nutzen zu können, müssen Sie bereits in der Lage sein, sowohl lokale als auch Remote-Verbindungen über denselben Istio-Setup zu kompilieren.

Übergeben Sie das Flag --internal_spawn_scheduler an Istio, um das dynamische Ausführungsmodul zu aktivieren. Dadurch wird eine neue Ausführungsstrategie namens dynamic hinzugefügt. Das können Sie jetzt als Strategie für die mnemonischen Komponenten verwenden, die Sie dynamisch ausführen möchten, z. B. --strategy=Javac=dynamic. Im nächsten Abschnitt erfahren Sie, wie Sie die Dynamik auswählen, für die die dynamische Ausführung aktiviert werden soll.

In jeder Dynamik wird mithilfe der dynamischen Strategie die Strategie für die Remote-Ausführung mit dem Flag --dynamic_remote_strategy und lokale Strategien mit dem Flag --dynamic_local_strategy übernommen. Wenn Sie --dynamic_local_strategy=worker,sandboxed übergeben, wird der Standard für den lokalen Zweig der dynamischen Ausführung festgelegt, um ihn mit Workern oder der Ausführung in einer Sandbox in dieser Reihenfolge auszuprobieren. Die Übergabe von --dynamic_local_strategy=Javac=worker überschreibt die Standardeinstellung nur für die Javac-Erinnerungsspeicher. Die Remote-Version funktioniert auf die gleiche Weise. Beide Flags können mehrmals angegeben werden. Wenn eine Aktion nicht lokal ausgeführt werden kann, wird sie wie gewohnt per Remotezugriff ausgeführt und umgekehrt.

Wenn Ihr Remotesystem einen Cache hat, wird das Flag --experimental_local_execution_delay mit einer Verzögerung in Millisekunden der lokalen Ausführung hinzugefügt, nachdem das Remotesystem einen Cache-Treffer angegeben hat. Dadurch wird die lokale Ausführung verhindert, wenn wahrscheinlich mehr Cache-Treffer auftreten. Der Standardwert ist 1.000 ms, sollte jedoch etwas länger sein als Cache-Treffer. Die tatsächliche Zeit hängt sowohl vom Remote-System als auch davon ab, wie lange eine Fahrt dauert. In der Regel ist der Wert für alle Nutzer eines bestimmten Remote-Systems derselbe, es sei denn, einige von ihnen sind weit genug weg, um die Umlaufzeitlatenz hinzuzufügen. Mit den Bazel-Profiling-Funktionen können Sie ermitteln, wie lange typische Cache-Treffer dauern.

Die dynamische Ausführung kann mit einer lokalen Sandbox-Strategie sowie mit persistenten Workern verwendet werden. Persistente Worker werden automatisch mit Sandboxing ausgeführt, wenn sie mit dynamischer Ausführung verwendet werden, und können keine Multiplex-Worker nutzen. Bei Darwin- und Windows-Systemen ist die Sandbox-Strategie unter Umständen langsam. Sie können --experimental_reuse_sandbox_directories übergeben, um einen neuen Ansatz zur Beschleunigung von Sandbox-Systemen auf diesen Systemen auszuprobieren.

Die dynamische Ausführung kann auch mit der Strategie standalone ausgeführt werden. Wenn die Strategie standalone jedoch zu Beginn die Ausführung sperren muss, wird die Remotestrategie praktisch nicht blockiert. Das Flag --experimental_local_lockfree_output bietet eine Möglichkeit, dieses Problem zu umgehen. Dafür kann die lokale Ausführung direkt in die Ausgabe schreiben, sie wird aber bei der Remote-Ausführung abgebrochen, falls sie zuerst abgeschlossen wurde.

Wenn einer der Zweige der dynamischen Ausführung zuerst endet, aber ein Fehler auftritt, schlägt die gesamte Aktion fehl. Dies ist eine absichtliche Option, um zu verhindern, dass Unterschiede zwischen der lokalen und der Remote-Ausführung unbemerkt bleiben.

Mehr zur dynamischen Ausführung und zu ihrem Sperren erfahren Sie in den exklusiven Blogposts von Julio Merino.

Wann sollte ich dynamische Ausführungen verwenden?

Für die dynamische Ausführung ist eine Form eines Remote-Ausführungssystems erforderlich. Es ist derzeit nicht möglich, ein ausschließlich im Cache gespeichertes Remote-System zu verwenden, da ein Cache-Fehler als fehlgeschlagene Aktion betrachtet wird.

Nicht alle Arten von Aktionen eignen sich gut für die Remote-Ausführung. Die besten Kandidaten sind diejenigen, die lokal grundsätzlich schneller sind, z. B. durch den Einsatz von nichtflüchtigen Workern oder solche, die so schnell ausgeführt werden, dass der Arbeitsaufwand für die Remote-Ausführung die Ausführungszeit dominiert. Da jede lokal ausgeführte Aktion eine gewisse Menge an CPU- und Arbeitsspeicherressourcen sperrt, werden durch die Ausführung von Aktionen, die in diese Kategorien fallen, diese nicht mehr ausgeführt.

Seit dem Release 5.0.0-pre.20210708.4 enthält die Leistungsprofile Daten zur Ausführung von Workern, einschließlich der Zeit, die für das Ausführen einer Arbeitsanfrage nach dem Verlust eines dynamischen Ausführungsrennens benötigt wird. Wenn Sie feststellen, dass die dynamischen Worker-Threads für die Ausführung sehr viel Zeit oder mit viel Zeit in async-worker-finish verbringen, kann es bei einigen lokalen Aktionen zu Verzögerungen bei den Worker-Threads kommen.

Profilerstellung für Daten mit schlechter dynamischer Ausführungsleistung

Das Profil oben, das acht Javac-Worker verwendet, hat gezeigt, dass viele Java-Worker die Rennen verloren haben und ihre Arbeit an den async-worker-finish-Threads beendet haben. Dies wurde durch ein Gedächtnis verursacht, das keine Worker war, die genügend Ressourcen benötigten, um die Worker zu verzögern.

Profilerstellung für Daten mit besserer dynamischer Ausführungsleistung

Wenn nur Javac mit dynamischer Ausführung ausgeführt wird, verlieren nur etwa die Hälfte der gestarteten Worker das Rennen, nachdem sie mit ihrer Arbeit begonnen haben.

Das zuvor empfohlene Flag --experimental_spawn_scheduler wurde verworfen. Die dynamische Ausführung wird aktiviert und dynamic wird als Standardstrategie für alle Benachrichtigungen festgelegt. Das würde oft zu solchen Problemen führen.

Fehlerbehebung

Probleme bei der dynamischen Ausführung können geringfügig und schwer zu beheben sein, da sie sich nur unter bestimmten spezifischen Kombinationen aus lokaler und Remote-Ausführung umsetzen lassen. Mit --experimental_debug_spawn_scheduler wird eine zusätzliche Ausgabe vom dynamischen Ausführungssystem hinzugefügt, das bei der Behebung dieser Probleme helfen kann. Sie können auch das Flag --experimental_local_execution_delay und die Anzahl der Remote- und lokalen Jobs anpassen, um die Reproduzierung der Probleme zu vereinfachen.

Wenn du Probleme mit der dynamischen Ausführung mit der Strategie standalone hast, versuche, sie ohne --experimental_local_lockfree_output auszuführen, oder führe deine lokalen Aktionen in einer Sandbox aus. Dadurch kann dein Build etwas langsamer werden (siehe oben, wenn du unter Mac oder Windows spielst), aber es werden einige mögliche Fehlerursachen entfernt.