Startseite
» Gewusst wie
»
Begrenzen Sie die CPU- und Speichernutzung eines Befehls mit Ubuntu cgroups
Begrenzen Sie die CPU- und Speichernutzung eines Befehls mit Ubuntu cgroups
Wenn ein Befehl Ihren Ubuntu-Desktop verlangsamt oder zu Speichermangel auf dem Server führt, platzieren Sie den Befehl und seine Kindprozesse in einer von systemd verwalteten Cgroup mit CPU- und Speicherlimit. Bei aktuellen Ubuntu-Versionen systemd-run --scopeist dies der kürzeste praktikable Weg: Der Befehl wird in einem temporären Gültigkeitsbereich gestartet, und systemd wendet die Limits über die Cgroup-Steuerung an.
Das folgende Beispiel begrenzt die Arbeitslast auf die Hälfte der CPU-Kapazität und 1 GiB Arbeitsspeicher. Diese Grenzwerte gelten für den gesamten Bereich, einschließlich untergeordneter Prozesse; sie stellen keine Garantie für eine bestimmte Programmgeschwindigkeit dar.
Warum ein Prozess ein Cgroup-Limit benötigt
Ein stark ausgelasteter Prozess kann mit interaktiven Anwendungen konkurrieren, während ein speicherintensiver Prozess den Speicherverbrauch des Systems erhöhen oder zu einem Speichermangel führen kann. Eine Cgroup gruppiert einen Prozess mit seinen Nachfolgern, sodass der Kernel diese Gruppe verwalten und einschränken kann. Ubuntus systemd bietet eine komfortable Schnittstelle für diese Steuerungsmöglichkeiten.
Die CPU- und Speichereinstellungen verhalten sich unterschiedlich. CPUQuota=50%Die CPU-Zeit wird auf die Hälfte der Kapazität einer CPU begrenzt, gemittelt über einen Planungszeitraum. Ein Wert von 0 200%entspricht der Zeit von bis zu zwei CPUs, sofern verfügbar. Dies ist ein Grenzwert, keine CPU-Priorität oder Reservierung. MemoryMax=1GEs wird ein fester Grenzwert für den der Cgroup zugewiesenen Speicher festgelegt. Wenn die Arbeitslast diesen Grenzwert nicht unterschreiten kann, kann der Kernel Speicher freigeben oder einen Prozess in dieser Cgroup aufgrund von Speichermangel beenden. Wählen Sie einen Grenzwert mit ausreichendem Spielraum für die Anwendung und ihre Kindprozesse.
1. Überprüfen Sie, ob Ubuntu cgroup v2 verwendet.
Ubuntu-Systeme mit systemd verwenden üblicherweise die einheitliche cgroup-v2-Hierarchie. Überprüfen Sie die aktive Konfiguration, bevor Sie sich auf die später angezeigten Pfade verlassen:
stat -fc %T /sys/fs/cgroup
systemctl --version | head -n 1
Der erste Befehl sollte eine Fehlermeldung ausgeben cgroup2fs. Falls er einen anderen Dateisystemtyp meldet, sind die in diesem Artikel beschriebenen cgroup v2-Dateipfade nicht anwendbar. Die systemd-Eigenschaften werden möglicherweise weiterhin mit einer anderen Hierarchie unterstützt; verwenden Sie jedoch die entsprechende Dokumentation Ihrer Distribution, anstatt v2-Pfade zu kopieren.
Prüfen Sie außerdem die genaue systemd-Version, falls eine Eigenschaft abgelehnt wird. Die Noble-Dokumentation von Ubuntu beschreibt CPUQuota=diese MemoryMax=als Ressourcenkontrolleinstellungen; ältere Ubuntu-Versionen können andere systemd-Versionen enthalten.
2. Beginnen Sie die Arbeitslast innerhalb eines begrenzten Bereichs
Führen Sie das Programm über den Befehl aus systemd-runund ersetzen Sie dabei die tatsächliche ausführbare Datei und die Argumente. Für einen Befehl im aktuellen Verzeichnis verwenden Sie den Befehl ./und übergeben alle Argumente nach dem Doppelpunkt --.
Führe einen Befehl innerhalb eines temporären systemd-Bereichs mit CPU- und Speicherbeschränkungen aus.
Bei einem benutzereigenen Befehl versuchen Sie es sudozunächst ohne Root-Rechte. Meldet systemd, dass ein angeforderter Controller oder eine Eigenschaft nicht verfügbar ist, fehlt dem Benutzer möglicherweise die Berechtigung, diese zu delegieren. Ein erneuter Versuch als Root kann bei systemweiten Aufgaben sinnvoll sein, ändert aber den Sicherheitskontext des Befehls. Führen Sie nicht ohne Weiteres ein nicht vertrauenswürdiges Programm als Root aus. Falls die Verwendung des Systemmanagers als Root erforderlich ist, sudo systemd-run --scope ...berücksichtigen Sie diese Änderung erst.
Das Terminal bleibt während der Befehlsausführung mit dem Gültigkeitsbereich verbunden. Durch Drücken Ctrl+Cder entsprechenden Taste wird der Vordergrundvorgang unterbrochen. Der Gültigkeitsbereich ist temporär und verschwindet normalerweise nach Beendigung der Prozesse. Er eignet sich gut, um einen Befehl innerhalb bestimmter Grenzen zu starten, und ist keine dauerhafte Richtlinie für zukünftige Ausführungen.
3. Ermitteln Sie den Anwendungsbereich und prüfen Sie seine Grenzen.
systemd-runGibt den Namen der erstellten Einheit aus, typischerweise etwas wie „ run-….scope“. Während der Befehl noch ausgeführt wird, wird der Cgroup-Baum aufgelistet:
systemd-cgls
Ermitteln Sie den temporären Gültigkeitsbereich und vergewissern Sie sich, dass das Zielprogramm und seine Kindprogramme darunter liegen. Dies ist wichtig, da ein Kindprogramm, das außerhalb des Gültigkeitsbereichs ausgeführt wird, nicht von derselben Cgroup-Obergrenze abgedeckt wird.
Verwenden Sie den cgroup-Baum, um zu bestätigen, dass das Programm und seine Worker im transienten Gültigkeitsbereich gruppiert sind.
Verwenden Sie den gedruckten Bereichsnamen im nächsten Befehl. Ersetzen Sie „ run-abc.scopedurch den tatsächlichen Namen“:
systemctl show run-abc.scope \
-p ControlGroup -p CPUQuotaPerSecUSec -p MemoryMax
CPUQuotaPerSecUSec=50000Dies entspricht einer 50%-Quote, wenn die Quotenperiode von systemd 100 ms beträgt; MemoryMax=1073741824es entspricht 1 GiB in Byte. Die Live-Werte sind aussagekräftiger als die Annahme, dass jeder Host jede Anfrage unverändert akzeptiert, da übergeordnete Cgroups und verfügbare Controller das effektive Ergebnis einschränken können.
Überprüfen Sie die vom Oszilloskop gemeldete Kontrollgruppe und die konfigurierten CPU- und Speicherkapazitätsgrenzen.
4. Kernel-Cgroup-Dateien überprüfen und sicher anpassen
Die ControlGroupEigenschaft gibt den Pfad zur Cgroup relativ zu an /sys/fs/cgroup. Speichern Sie ihn in einer Shell-Variablen, damit die Befehle dem tatsächlich auf Ihrem Rechner zugewiesenen Pfad folgen:
Bei cgroup v2 cpu.maxenthält die Variable ein Kontingent und einen Zeitraum in Mikrosekunden. Beispielsweise 50000 100000bedeutet dies 50 ms CPU-Zeit pro 100 ms. memory.maxDie Variable zeigt die Speicherobergrenze in Bytes an. Falls die Dateien fehlen, überprüfen Sie, ob der Bereich noch aktiv ist und der Kernel cgroup v2 verwendet.
Lesen Sie die cgroup v2-Dateien des Kernels, um die konfigurierte Quote und Speicherobergrenze zu überprüfen.
Wenn Sie eine benannte, langlaufende Unit gestartet haben und deren Limits anpassen müssen, unterstützt systemd beispielsweise das Ändern von Ressourceneigenschaften einer aktiven Unit sudo systemctl set-property --runtime my-worker.service CPUQuota=50% MemoryMax=1G. Dies betrifft die Cgroup des Dienstes und erfordert entsprechende Berechtigungen. Ein bereits laufender Prozess wird nicht automatisch angehängt, nur weil seine PID bekannt ist. Bei einem einmaligen Prozess muss dieser ordnungsgemäß beendet und anschließend über den begrenzten Bereich neu gestartet werden. Bei einem persistenten Dienst konfigurieren Sie die Eigenschaften in der Dienst-Unit oder einem systemd-Drop-in und starten diesen während eines geeigneten Wartungsfensters neu.
Ergebnis prüfen
Lassen Sie die Arbeitslast aktiv, während Sie sie untersuchen. Stellen Sie sicher, dass systemd-cglsder Prozess und seine Kindprozesse im vorgesehenen Bereich liegen, systemctl showdie angeforderten Eigenschaften gemeldet werden und die entsprechenden cpu.maxDateien memory.maxmit endlichen Werten vorhanden sind. Beim Beenden des Prozesses wird der temporäre Bereich entfernt, sodass die zugehörigen Cgroup-Dateien möglicherweise verschwinden.
Ein Quota begrenzt die CPU-Zeit, garantiert aber keinen festen Prozentsatz auf dem Desktop-Monitor. Eine feste Speicherbegrenzung kann zu Fehlern führen, wenn die Anwendung mehr Speicher benötigt. Bei instabiler Arbeitslast sollten Sie die Anwendung stoppen und das Limit auf einen sicheren Wert erhöhen oder einen flexibleren MemoryHigh=Schwellenwert in Kombination mit einem höheren Wert verwenden MemoryMax=. Genaue Informationen zum Verhalten finden Sie in der Dokumentation Ihres installierten systemd und Kernels. Die maßgeblichen Referenzen sind das Ubuntu-Handbuch zu systemd-run , das Ubuntu-Handbuch zu systemd resource-control und die Dokumentation zu cgroup v2 des Linux-Kernels .