Home
» LINUX
»
Come limitare l'utilizzo di CPU e RAM di un processo con i cgroup su Ubuntu
Come limitare l'utilizzo di CPU e RAM di un processo con i cgroup su Ubuntu
Su Ubuntu, il modo più sicuro in generale per limitare un carico di lavoro con i cgroup è lasciare che systemd crei e gestisca il suo gruppo di controllo. Usalo systemd-runper un comando che stai avviando ora, oppure configura un servizio systemd quando il limite deve persistere anche dopo i riavvii. Imposta CPUQuota=un limite massimo rigido per il tempo CPU e scegli tra MemoryHigh=per la pressione e MemoryMax=per un limite rigido di memoria. Questi limiti si applicano all'unità e ai suoi processi figli insieme.
Un cgroup (gruppo di controllo) è un meccanismo del kernel Linux che organizza i processi in modo che il sistema possa monitorare e controllare il loro utilizzo delle risorse. Il sistema systemd di Ubuntu inserisce già i servizi nei cgroup, quindi la maggior parte degli utenti non ha bisogno di creare /sys/fs/cgroupmanualmente le directory al loro interno. Gli esempi seguenti utilizzano l'interfaccia di controllo delle risorse di systemd e dovrebbero essere verificati con la versione di systemd installata sulla propria distribuzione Ubuntu.
Esempio illustrativo di terminale per verificare systemd e il mount di cgroup v2. La versione e l'output visualizzati sono esempi e non rappresentano il risultato di un test.
Scegli il controllo che corrisponde al problema
Metodo
Ciò che controlla
Migliore vestibilità
Principale compromesso
systemd-runambito transitorio
Quota CPU e limiti di memoria per un comando appena avviato e i suoi discendenti
Una compilazione, uno script, un'importazione o un'attività batch una tantum.
L'ambito è temporaneo e termina con il carico di lavoro; non si collega a un processo arbitrario già in esecuzione.
impostazioni del servizio systemd
Risorse per il cgroup del servizio, inclusi i processi secondari
Un demone o un'applicazione che deve mantenere gli stessi limiti dopo il riavvio.
Richiede la configurazione del servizio e in genere un riavvio per applicare le nuove impostazioni.
File cgroup v2 diretti
Controller a livello di kernel come cpu.maxememory.max
Runtime dei container, gestori cgroup delegati o amministrazione specializzata
È un processo più manuale; systemd gestisce gran parte della gerarchia di Ubuntu e la scrittura nel suo albero gestito può entrare in conflitto con systemd o fallire a causa di problemi di permessi e delega.
niceOCPUWeight=
Priorità relativa della CPU quando i gruppi competono
Mantenere la priorità delle attività in background più bassa, consentendo loro al contempo di utilizzare la CPU inattiva.
Non si tratta di un limite rigido per la CPU e non limita la memoria.
Per la maggior parte delle macchine Ubuntu interattive, un ambito transitorio è la scelta più rapida e reversibile. Per un servizio di produzione, utilizzare l'unità di servizio in modo che la policy sia documentata e ripristinata all'avvio. Utilizzare file cgroup diretti solo quando si gestisce intenzionalmente una gerarchia delegata o si sta creando un flusso di lavoro container/runtime.
Verifica il sistema Ubuntu prima di impostare i limiti
Innanzitutto, verifica che systemd sia disponibile e che il filesystem cgroup sia unificato v2:
systemctl --version
stat -fc %T /sys/fs/cgroup
Il risultato cgroup2fsdel secondo comando indica il filesystem cgroup v2 unificato. Le versioni di Ubuntu e i sistemi personalizzati possono differire, quindi non dare per scontato che ogni macchina abbia la stessa gerarchia o le stesse funzionalità di systemd. Puoi anche controllare la versione corrente di systemd con il primo comando. Se il mount cgroup non è v2, alcune proprietà delle risorse o il comportamento del controller potrebbero essere diversi; consulta la pagina del manuale di Ubuntu per la versione installata prima di copiare una configurazione.
Scegliete i valori dopo aver misurato il carico di lavoro. Lasciate spazio per il resto del sistema e ricordate che i limiti impostati su un servizio utente sono vincolati anche da eventuali limiti sulla sua slice padre. Un cgroup figlio non può ricevere più risorse di quelle consentite da un antenato.
Limita un comando che stai per avviare
Per un comando nella tua sessione utente, avvialo in un ambito transitorio con systemd-run --user --scope. Ad esempio:
Esempio illustrativo di un comando systemd-run eseguito una tantum, con quota CPU, soglia di pressione della memoria e limite massimo di memoria.
Sostituisci il comando Python con il programma che devi effettivamente eseguire. Questo esempio assegna al cgroup una larghezza di banda massima della CPU equivalente alla metà di una CPU, inizia la gestione della pressione della memoria intorno ai 700 MiB e imposta un massimo di memoria fisica di 900 MiB. I valori della memoria utilizzano le unità in base 1024 di systemd. Una quota 100%rappresenta il tempo di una CPU; 200%può utilizzare fino a due CPU quando disponibili. Non rappresenta una percentuale di tutti i core del computer.
Il comando viene eseguito in primo piano perché si tratta di un ambito. Quando termina, l'unità temporanea scompare. Rimuoverla --usersolo se si intende utilizzare il gestore di sistema e si dispone dei privilegi necessari; per un'unità temporanea a livello di sistema, eseguire il comando con sudoe utilizzare le opzioni di comando appropriate. Le impostazioni delle risorse potrebbero essere rifiutate se il gestore o il controller cgroup non le supportano.
Imposta dei limiti per un servizio systemd persistente
Per un servizio come worker.service, crea un componente aggiuntivo invece di modificare il file dell'unità del fornitore. Esegui sudo systemctl edit worker.servicee aggiungi:
Esempio di configurazione del servizio systemd con controlli persistenti di CPU e memoria. Utilizzare il nome del servizio e i valori reali appropriati al proprio carico di lavoro.
Salva il drop-in, quindi ricarica le definizioni delle unità di systemd e riavvia il servizio in modo che il processo venga avviato secondo i criteri modificati:
Utilizzare un limite di memoria prudente. Se il servizio non riesce a recuperare memoria a sufficienza al di sotto di un certo valore MemoryMax, il kernel potrebbe richiamare il killer di memoria insufficiente all'interno di quel cgroup. Ciò può terminare uno o più processi nel gruppo di servizi e interrompere il lavoro. Un approccio più sicuro consiste spesso nell'impostare MemoryHighun valore in cui il recupero e la limitazione della memoria siano accettabili, per poi impostare MemoryMaxun limite superiore come limite finale. Eseguire test con carichi di picco realistici prima di implementare limiti più stringenti.
Verifica l'unità e osservane il comportamento.
Per l'ambito transitorio, verifica il suo stato utilizzando il nome dell'unità che hai fornito:
Visualizzazione illustrativa dello stato e del monitor cgroup. I valori di CPU e memoria mostrati qui non sono misurazioni effettuate durante un'esecuzione reale.
systemctl --user status worker-capped.scope
systemd-cgtop
Per un servizio di sistema, omettere --usernel comando di stato. La vista di stato conferma che l'unità esiste ed è attiva; systemd-cgtopmostra l'utilizzo delle risorse in tempo reale per gruppo di controllo. Per ispezionare le proprietà configurate, interrogare direttamente l'unità, ad esempio:
La memoria riportata per un cgroup non corrisponde necessariamente al valore residente di un singolo processo: tiene conto della memoria allocata al gruppo e può includere i processi discendenti del carico di lavoro. Il monitoraggio va considerato come un indicatore del comportamento del carico di lavoro nel tempo, non come un singolo valore da ottimizzare ciecamente.
E se il processo fosse già in esecuzione?
systemd-runAvvia un nuovo comando all'interno di una nuova unità; non prende un PID esistente arbitrario e lo sposta in quell'ambito. Se il processo appartiene a un servizio systemd, applica le impostazioni a quel servizio con un drop-in oppure, per una modifica temporanea, usa sudo systemctl set-property --runtime worker.service CPUQuota=50% MemoryHigh=700M MemoryMax=900M. La --runtimeforma è temporanea e non sostituisce una configurazione di servizio persistente.
Se il processo è un programma normale nella sessione desktop, il metodo semplice e sicuro è solitamente quello di arrestarlo e riavviarlo systemd-run. Applicare una proprietà a una porzione più ampia, come l'intera porzione utente, può influire su molte applicazioni non correlate. Spostare un processo scrivendo il suo PID in un file cgroup richiede il controllo della gerarchia delegata pertinente e deve rispettare le regole di posizionamento dei processi di cgroup v2; non scrivere nelle directory gestite da systemd a caso.
Come scegliere una politica per CPU e memoria
Hai bisogno di un limite massimo per la CPU? Scegli CPUQuota=. Valori inferiori riducono il consumo massimo della CPU, ma possono rallentare il completamento e aumentare i tempi di attesa.
Hai bisogno solo di una priorità inferiore? Considera CPUWeight=invece una quota. Il peso condivide la CPU in modo relativo in caso di contesa; non riserva una percentuale fissa né impedisce l'utilizzo della CPU inattiva.
Hai bisogno di esercitare pressione sulla memoria senza un arresto immediato e brusco? Impostala MemoryHigh=come soglia di pressione principale e osserva la latenza e il comportamento di recupero.
È necessario un limite di contenimento finale? Aggiungere MemoryMax=un margine sufficiente per i picchi normali. Prepararsi a un comportamento di esaurimento della capacità (OOM) quando il limite non può essere rispettato.
Stai già utilizzando un container? Preferisci i flag di CPU e memoria supportati dal gestore dei container, che configurano i cgroup per quel container e si adattano al suo ciclo di vita.
Non esiste un limite ideale univoco per ogni carico di lavoro. Un processo batch desktop può tollerare una quota bassa e un limite di memoria moderato; un servizio sensibile alla latenza potrebbe richiedere una maggiore riserva di CPU e un valore più elevato MemoryHighper evitare pause dovute al recupero delle risorse. Iniziate con impostazioni prudenti, monitorate il dispositivo durante un picco rappresentativo e regolate un'impostazione alla volta.