Il comportamento predefinito di "bello" è di regolare la priorità "io" dell'applicazione anche quando cambia la gentilezza.
Ovviamente tutto dipende dal carico di lavoro, ma uno degli aspetti chiave di qualsiasi sistema operativo è il modo in cui alloca la sua risorsa e come gestisce la contesa .
In realtà è importante capire cosa fa la gentilezza perché quando sotto carico da processi concorrenti il modo in cui si comporta il sistema operativo può avere un impatto sul resto del carico di lavoro.
La contesa è la misura di come diverse applicazioni competono per la stessa risorsa (come la CPU).
Gestione del carico
Da quando è stato introdotto lo scheduler completamente corretto, nice è semplicemente un frontend alla clausola "peso" di ogni processo. Che può essere visualizzato in proc.
$ cat /proc/self/sched
---------------------------------------------------------
...
se.load.weight : 1024
...
La modifica della gentilezza altera semplicemente il peso:
$ nice -n 5 cat /proc/self/sched
---------------------------------------------------------
...
se.load.weight : 335
...
La misura per la contesa della CPU viene eseguita dall'algoritmo di programmazione completamente corretto. A ogni applicazione viene assegnato un valore di "peso" e, nel caso di contendere il tempo della CPU, il tempo viene suddiviso tra i processi sommando tutta l'elaborazione contendendosi per il tempo della CPU e assegnando loro il tempo di CPU di denominazione comune più basso in base al loro valore di peso.
Se ho 3 applicazioni che vogliono usare il tempo della CPU, per impostazione predefinita ricevono 1024 come peso normale. Se avessi un processo con un bel +5 come sopra, tutti e tre i pesi sarebbero stati sommati a 2383, il processo niced riceverebbe quindi circa il 15% del tempo della CPU in un dato secondo se tutti e 3 i processi richiedessero la CPU in quel secondo .
Perché è necessario avere priorità CPU e I / O diverse?
La gentilezza gioca davvero solo con cosa fare quando il sistema è sotto carico, ovvero come il sistema operativo suddivide il tempo tra i processi concorrenti come definito da qualunque fattore sia necessario.
Il modo in cui ciò influisce su di te o è pertinente per te è legato a quali priorità di consegna hanno le diverse applicazioni tra loro e il tempo di consegna di ciascuna applicazione dovrebbe avere.
La gentilezza fa davvero qualcosa solo quando il tuo sistema è sotto carico (ci sono più cose che richiedono attenzione di quante ne possano gestire la CPU o il disco). Indica semplicemente al kernel come allocare le risorse in tali circostanze.
C'è qualche utilizzo nel mondo reale per averli diversi?
Se hai numerosi processi in competizione o lavori da svolgere che sono più di quanto possa essere fatto dalla CPU, la gentilezza ti dà alcune garanzie relativamente stabili su ciò che il lavoro finisce per primo. Questo può essere importante per te se dici di produrre un rapporto che dovrebbe essere consegnato prima che un altro rapporto finisca.
Su un sistema desktop la gentilezza può essere ancora più importante. Alcune applicazioni hanno un comportamento in tempo reale in base al quale vengono svegliate più spesso durante il caricamento per evitare che i dati diventino obsoleti. Pulseaudio rientra in questa categoria per esempio.
Potrebbero essere necessarie altre applicazioni per fornire lavoro per applicazioni dipendenti. Ad esempio molte richieste di Apache per dire che un server SQL come MySQL potrebbe bloccarsi per un lungo periodo di tempo perché SQL non viene pubblicato abbastanza velocemente perché - diciamo che altri report sono in competizione per il tempo della CPU. Quindi non solo SQL è bloccato ma anche Apache. Qui a volte l'SQL può ferire perché di solito ci sono molti meno thread di lavoro rispetto ai thread di Apache in competizione come gruppo per essere valutati più favorevolmente dallo scheduler, quindi dare più tempo alla CPU su SQL equilibra le cose.
UpdateDB (un programma che indicizza i file) viene eseguito a tarda notte ed è molto pesante sul disco. Può essere utile ridurre la sua priorità di pianificazione IO in modo che altre applicazioni in quel momento abbiano la priorità su qualcosa che non è così importante nell'ordine delle cose.
Quali casi di utilizzo nel mondo reale hai trovato che richiedono priorità diverse di CPU e I / O?
Pochissimi. La gentilezza è un approccio troppo efficace. Come regola generale, mi preoccupo meno delle prestazioni delle applicazioni e più di quanto male possano funzionare. All'inizio questo potrebbe sembrare all'indietro, ma ho delle garanzie di consegna del servizio che sono più importanti per me.
Voglio la fiducia per dire "le tue cose anche in una brutta giornata saranno fatte nel periodo di tempo X". Se va più veloce, è solo un bonus.
In genere inizierò generando specifiche concordate come:
- Tutte le applicazioni web sono garantite per completare le richieste in 0,3 secondi.
- Tutte le richieste SQL su un sistema sono garantite per essere completate in 0,1 secondi.
- L'applicazione Web non deve gestire più di 50 IOPS e fornisce file 1k.
- L'impronta di memoria delle applicazioni Web non è superiore a 250 Mb in totale.
E definire i requisiti per soddisfare come:
- Tutte le richieste Web devono essere completate in 0,05 secondi.
- Tutte le richieste SQL devono essere completate in 0,02 secondi.
- Dovrebbe esserci memoria sufficiente per gestire tutte le richieste.
- I requisiti di IO devono essere soddisfatti.
Fornendo le specifiche vere, allora raggiungo questi obiettivi senza fare virtualizzazione, usando l'approccio molto più efficiente dei gruppi di controllo.
I gruppi di controllo mi consentono di fornire garanzie di livello di servizio abbastanza affidabili per l'allocazione delle risorse, a condizione che l'applicazione si comporti entro i limiti specificati. Ciò significa che anche su un sistema sotto carico posso garantire la disponibilità delle risorse per l'applicazione in questione e garantire spazio per altre applicazioni nella stessa scatola!
Se prendiamo il tuo esempio di CPU e IO. Ho impostato dei limiti che soddisfano tali requisiti:
# cd /sys/fs/cgroup/blkio/apache
# echo "253:0 100" >blkio.throttle.read_iops_device
# echo "253:0 50" >blkio.throttle.write_iops_device
# echo "253:0 102400" >blkio.throttle.read_bps_device
Quindi 100k byte da leggere di 100 iops.
# cd /sys/fs/cgroup/cpu/apache
# echo 1000000 >cpu.cfs_period_us
# echo 60000 >cpu.cfs_quota_us
Per un periodo di 1 secondo, fornire 0,06 secondi di CPU.
# cd /sys/fs/cgroup/cpu/sql
# echo 1000000 >cpu.cfs_period_us
# echo 20000 >cpu.cfs_quota_us
Per un periodo di 1 secondo, fornire 0,02 secondi di CPU.
Fornire altri cgroups concorrenti non fa nulla di stupido, essere sotto carico è un fattore meno importante nella fornitura del mio servizio perché so come viene lanciata la CPU per ogni applicazione.
I gruppi di controllo di questa natura sono ancora i migliori sforzi ma offrono molto più controllo su quello sforzo rispetto alla gentilezza e alla ionicità.