Home
» Hoe
»
Beperk het CPU- en geheugengebruik van een commando met Ubuntu cgroups.
Beperk het CPU- en geheugengebruik van een commando met Ubuntu cgroups.
Als een commando je Ubuntu-desktop traag maakt of ervoor zorgt dat een server geheugenproblemen krijgt, plaats het commando en de bijbehorende processen dan in een door systemd beheerde cgroup met een CPU-quotum en een geheugenlimiet. In de huidige Ubuntu-versies systemd-run --scopeis dit de kortste praktische oplossing: het start het commando in een tijdelijke scope en systemd past de limieten toe via cgroup-controls.
Het onderstaande voorbeeld beperkt de werkbelasting tot de helft van de capaciteit van één CPU en 1 GiB geheugen. Dit zijn limieten voor het gehele proces, inclusief subprocessen; ze garanderen niet dat het programma op een bepaalde snelheid zal draaien.
Waarom een proces een cgroup-limiet nodig heeft
Een druk proces kan concurreren met interactieve applicaties, terwijl een geheugenintensief proces de machine in een geheugenherstelmodus kan brengen of een 'out-of-memory'-situatie kan veroorzaken. Een cgroup groepeert een proces met zijn afstammelingen, zodat de kernel die groep kan beheren en beperken. Ubuntu's systemd biedt een handige interface voor deze beheermogelijkheden.
CPU- en geheugeninstellingen gedragen zich verschillend. CPUQuota=50%De CPU-tijd wordt beperkt tot de helft van de capaciteit van één CPU, gemiddeld over een planningsperiode. Een waarde van 100 200%vertegenwoordigt de tijd van maximaal twee CPU's, indien beschikbaar. Dit is een maximum, geen CPU-prioriteit of reservering. De geheugenlimiet MemoryMax=1Gstelt een harde bovengrens in voor het geheugen dat aan de cgroup wordt toegewezen; als de werkbelasting niet onder deze limiet kan blijven, kan de kernel geheugen vrijmaken of een out-of-memory kill uitvoeren voor een proces in die cgroup. Kies een limiet met voldoende ruimte voor de applicatie en de onderliggende processen.
1. Controleer of Ubuntu cgroup v2 gebruikt.
Ubuntu-systemen die systemd gebruiken, hanteren doorgaans de uniforme cgroup v2-hiërarchie. Controleer de actieve configuratie voordat u vertrouwt op de paden die later worden weergegeven:
stat -fc %T /sys/fs/cgroup
systemctl --version | head -n 1
Het eerste commando zou moeten rapporteren cgroup2fs. Als het een ander bestandssysteemtype rapporteert, zijn de cgroup v2-bestandspaden in dit artikel niet van toepassing zoals ze beschreven staan. De systemd-eigenschappen worden mogelijk nog steeds ondersteund met een andere hiërarchie, maar gebruik in dat geval de bijbehorende distributiedocumentatie in plaats van de v2-paden te kopiëren.
Controleer ook de exacte systemd-versie als een eigenschap wordt afgewezen. De Noble-documentatie van Ubuntu beschrijft CPUQuota=en MemoryMax=als instellingen voor resourcebeheer; oudere Ubuntu-releases kunnen andere systemd-versies bevatten.
2. Start de werkzaamheden binnen een beperkt toepassingsgebied.
Voer het programma uit met behulp van systemd-runde opdracht `executable`, waarbij u het daadwerkelijke uitvoerbare bestand en de argumenten vervangt. Voor een opdracht in de huidige map gebruikt u de opdracht `executable` ./en geeft u alle argumenten na `:` door --.
Voer een commando uit binnen een tijdelijke systemd-scope met CPU- en geheugenlimieten.
Probeer voor een door de gebruiker beheerd commando dit sudoeerst zonder root. Als systemd meldt dat een aangevraagde controller of eigenschap niet beschikbaar is, heeft de gebruikersmanager mogelijk geen toestemming om deze te delegeren; opnieuw proberen als root kan geschikt zijn voor een systeemwijde workload, maar dit verandert de beveiligingscontext van het commando. Voer niet zomaar een onbetrouwbaar programma uit als root. Als het gebruik van de systeemmanager als root vereist is, doe dit sudo systemd-run --scope ...dan pas nadat u rekening hebt gehouden met deze wijziging.
De terminal blijft aan het bereik gekoppeld terwijl de opdracht wordt uitgevoerd. Door op te drukken Ctrl+Cwordt de voorgrondbewerking onderbroken. Het bereik is tijdelijk en verdwijnt normaal gesproken nadat de processen zijn afgesloten. Het is een handige manier om een opdracht binnen bepaalde beperkingen te starten, in plaats van een permanent beleid voor toekomstige uitvoeringen.
3. Bepaal het bereik en inspecteer de grenzen ervan.
systemd-runprint de naam van de eenheid die wordt aangemaakt, meestal iets als run-….scope. Terwijl het commando nog steeds actief is, toon je de cgroup-structuur:
systemd-cgls
Zoek het transient scope-bereik op en controleer of het doelprogramma en de bijbehorende subprogramma's eronder vallen. Dit is belangrijk, omdat een subprogramma dat buiten het scope-bereik draait, niet onder hetzelfde cgroup-plafond valt.
Gebruik de cgroup-structuur om te bevestigen dat het programma en de bijbehorende workers onder de transient-scope zijn gegroepeerd.
Gebruik de afgedrukte scopenaam in de volgende opdracht. Vervang run-abc.scopedoor de daadwerkelijke naam:
systemctl show run-abc.scope \
-p ControlGroup -p CPUQuotaPerSecUSec -p MemoryMax
CPUQuotaPerSecUSec=50000Dit komt overeen met een quotum van 50% wanneer de quotumperiode van systemd 100 ms is; MemoryMax=1073741824dit is 1 GiB in bytes. De live waarden zijn nuttiger dan de aanname dat elke host elk verzoek ongewijzigd accepteert, aangezien parent cgroups en beschikbare controllers het uiteindelijke resultaat kunnen beperken.
Controleer de door de oscilloscoop gerapporteerde besturingsgroep en de geconfigureerde CPU- en geheugenlimieten.
4. Controleer de kernel cgroup-bestanden en pas ze veilig aan.
Deze ControlGroupeigenschap geeft het cgroup-pad weer ten opzichte van /sys/fs/cgroup. Sla dit op in een shellvariabele, zodat de commando's het pad volgen dat daadwerkelijk op uw machine is toegewezen:
Bij cgroup v2 cpu.maxbevat dit een quotum en een periode in microseconden. Bijvoorbeeld, 50000 100000dit betekent 50 ms CPU-tijd in elke periode van 100 ms. memory.maxHet toont de geheugenlimiet in bytes. Als de bestanden ontbreken, controleer dan of het bereik nog steeds actief is en of de kernel cgroup v2 gebruikt.
Lees de cgroup v2-bestanden van de kernel om het geconfigureerde quotum en de geheugenlimiet te controleren.
Als u een benoemde, langlopende eenheid hebt gestart en de limieten ervan wilt aanpassen, ondersteunt systemd het wijzigen van resource-eigenschappen op een actieve eenheid, bijvoorbeeld sudo systemctl set-property --runtime my-worker.service CPUQuota=50% MemoryMax=1G. Dit geldt voor de cgroup van die service en vereist de juiste privileges. Het koppelt geen willekeurig, reeds actief proces alleen omdat de PID bekend is; voor een eenmalig proces moet u het netjes stoppen en opnieuw starten via de beperkte scope. Voor een persistente service configureert u de eigenschappen in de service-eenheid of een systemd drop-in en start u deze opnieuw tijdens een geschikt onderhoudsvenster.
Controleer het resultaat
Houd de workload actief terwijl u deze inspecteert. Controleer of systemd-cglshet proces en de bijbehorende subprocessen zich binnen het beoogde bereik bevinden, of systemctl showde gevraagde eigenschappen worden gerapporteerd en of de corresponderende cpu.maxbestanden memory.maxbestaan met eindige waarden. Wanneer het proces wordt beëindigd, wordt het tijdelijke bereik verwijderd, waardoor de bijbehorende cgroup-bestanden mogelijk verdwijnen.
Een quotum beperkt de CPU-tijd, maar garandeert geen vast percentage op een desktopmonitor. Een harde geheugenlimiet kan storingen veroorzaken als de applicatie meer geheugen nodig heeft dan de limiet. Als de workload instabiel wordt, stop deze dan en verhoog de limiet naar een veilige waarde of gebruik een zachtere MemoryHigh=drukdrempel in combinatie met een hogere limiet MemoryMax=. Raadpleeg voor het exacte gedrag de documentatie van uw geïnstalleerde systemd en kernel; de gezaghebbende bronnen zijn de Ubuntu systemd-run handleiding , de Ubuntu systemd resource-control handleiding en de Linux kernel cgroup v2 documentatie .