Product SiteDocumentation Site

Capitolo 3. Sottosistemi e parametri regolabili

3.1. blkio
3.1.1. Opzioni di configurazione di Proportional Weight Division
3.1.2. Opzioni di configurazione di I/O Throttling
3.1.3. Comuni opzioni di configurazione
3.1.4. Esempio d'uso
3.2. cpu
3.3. cpuacct
3.4. cpuset
3.5. devices
3.6. freezer
3.7. memory
3.8. net_cls
3.9. ns
3.10. Risorse aggiuntive
I Sottosistemi sono moduli del kernel in grado di riconoscere i cgroup. Generalmente essi sono controllori di risorse che assegnano vari livelli di risorse di sistema a diversi cgroup. Comunque, i sottosistemi possono essere programmati per qualsiasi altra interazione con il kernel, dove esista la necessità di trattare in modo differente diversi gruppi di processi. Le API (Application Programming Interface), per sviluppare nuovi sottosistemi, sono documentate nel file cgroups.txt della documentazione del kernel del proprio sistema, disponibile in /usr/share/doc/kernel-doc-versione-kernel/Documentation/cgroups/ (fornita dal pacchetto kernel-doc). L'ultima versione della documentazione relativa ai cgroup, è disponibile anche online su http://www.kernel.org/doc/Documentation/cgroups/cgroups.txt. Da notare, tuttavia, che le funzioni nell'ultima versione della documentazione potrebbero non corrispondere a quelle presenti nel kernel del proprio sistema.
Gli State object che contengono i parametri di sottosistema per un cgroup, sono rappresentati come pseudofile nel file system virtuale di cgroup. Questi pseudo-file possono essere manipolati dai comandi di shell o da chiamate di sistema equivalenti. Per esempio, cpuset.cpus è uno pseudo-file che specifica a quali CPU può accedere un cgroup. Se /cgroup/cpuset/webserver è un cgroup per il server web in esecuzione su un sistema, e si esegue il seguente comando:
~]# echo 0,2 > /cgroup/cpuset/webserver/cpuset.cpus
Il valore 0,2 viene scritto sul pseudofile cpuset.cpus e limita quindi ogni task con un PID elencato in /cgroup/cpuset/webserver/tasks ad usare solo CPU 0 e CPU 2 sul sistema.

3.1. blkio

Il sottosistema Block I/O (blkio) amministra e controlla l'accesso di I/O sui dispositivi a blocchi in base ai task in cgroup. La scrittura in qualcuno di questi pseudofile limita l'accesso o la larghezza di banda, mentre la lettura fornisce informazioni sulle operazioni di I/O.
Il sottosistema blkio offre due policy per controllare l'accesso di I/O:
  1. Proportional weight division (Divisione a peso proporzionale) — Implementato nello schedulatore di I/O, Completely Fair Queuing, questa policy permette di impostare i pesi di cgroup specifici. Ciò significa che ciascun cgroup ha una percentuale di settaggio (dipendente dal peso del cgroup), di tutte le operazioni di I/O riservate. Per maggiori informazioni, fare riferimento alla Sezione 3.1.1, «Opzioni di configurazione di Proportional Weight Division».
  2. I/O throttling (Limite superiore) — usato per impostare un limite superiore al numero di operazioni di I/O eseguite da uno specifico dispositivo. Ciò significa che un dispositivo può avere un tasso limitato di operazioni di lettura o scrittura. Per maggiori informazioni, fare riferimento alla Sezione 3.1.2, «Opzioni di configurazione di I/O Throttling».

Operazioni di scrittura buffered

Allo stato attuale, il sottosistema Block I/O non funziona con le operazioni di scrittura buffered. Esso si rivolge in primo luogo ad I/O diretto, sebbene funzioni con le operazioni di lettura buffered.

3.1.1. Opzioni di configurazione di Proportional Weight Division

blkio.weight
specifica, per impostazione predefinita, la proporzione relativa (weight), di accesso del Block I/O ad un cgroup, nel range di valori compresi tra 100 e 1000. Questo valore viene sovrascritto per dispositivi specifici dal parametro blkio.weight_device. Per esempio, per assegnare un peso predefinito di 500 ad un cgroup per l'accesso ai dispositivi a blocchi, eseguire:
echo 500 > blkio.weight
blkio.weight_device
specifica la proporzione relativa (peso) di accesso all'I/O su dispositivi specifici ad un cgroup, nel range compreso fra 100 e 1000. Il valore di questo parametro sovrascrive il valore di blkio.weight per i dispositivi specificati. I valori presentano il seguente formato maggiore:minore peso, dove maggiore e minore corrispondono ai tipi di dispositivo ed ai numeri di nodo come specificati in Linux Allocated Devices, anche conosciuto come Linux Devices List e disponibile su http://www.kernel.org/doc/Documentation/devices.txt. Per esempio, per assegnare un peso di 500 ad un cgroup, per l'accesso al /dev/sda, eseguire:
echo 8:0 500 > blkio.weight_device
Nella notazione di Linux Allocated Devices, 8:0 rappresenta /dev/sda.
blkio.time
notifica il tempo nel quale un cgroup ha avuto accesso di I/O ai dispositivi specifici. Le voci presentano tre campi: maggiore, minore, e tempo. Maggiore e minore corrispondono ai tipi di dispositivo ed ai numeri di nodo specificati nel Linux Allocated Devices, e tempo è la durata del periodo, espresso in millisecondi (ms).
blkio.sectors
notifica il numero di settori trasferiti da/verso dispositivi specifici, da un cgroup. Le voci presentano tre campi: maggiore, minore, e settori. Maggiore e minore corrispondono ai tipi di dispositivo ed ai numeri di nodo specificati nei Linux Allocated Devices e settori è il numero di settori del disco.
blkio.io_serviced
notifica il numero di operazioni di I/O eseguite su dispositivi specifici da un cgroup come visto dallo schedulatore CFQ. Le voci sono quattro campi: maggiore, minore, operazione e numero. Maggiore e minore corrispondono ai tipi di dispositivo ed ai numeri di nodo specificati nei Linux Allocated Devices, operazione rappresenta il tipo di operazione (read, write, sync, o async) e numero rappresenta il numero di operazioni.
blkio.io_service_bytes
notifica il numero di byte trasferiti da/verso dispositivi specifici da un cgroup come visto dallo schedulatore CFQ. Le voci hanno quattro campi:maggiore, minore, operazione e byte. Maggiore e minore corrispondono ai tipi di dispositivo ed ai numeri di nodo specificati in Linux Allocated Devices, operazione rappresenta il tipo di operazione (read, write, sync, o async) e byte il numero di byte trasferiti.
blkio.io_service_time
notifica il tempo totale tra l'invio ed il completamento di richieste per operazioni di I/O su dispositivi specifici, da un cgroup come visto dallo schedulatore CFQ. Le voci hanno quattro campi:maggiore, minore, operazione e tempo. Maggiore e minore corrispondono ai tipi di dispositivo ed ai numeri di nodo specificati in Linux Allocated Devices, operazione rappresenta il tipo di operazione (read, write, sync, o async) e tempo è la durata del periodo in nanosecondi (ns). Il periodo è riportato in nanosecondi piuttosto che in unità maggiori, cosicché questo report è significativo anche per dispositivi a stato solido.
blkio.io_wait_time
notifica il tempo totale che le operazioni di I/O su dispositivi specifici di un cgroup, spendono in attesa di un servizio in coda dello scheduler. Per l'interpretazione di questo report notare che:
  • il tempo riportato può essere maggiore del tempo totale trascorso, poiché il tempo riportato è un periodo cumulativo di tutte le operazioni di I/O per il cgroup piuttosto che il periodo che il cgroup stesso ha speso in attesa delle operazioni di I/O. Per trovare il tempo speso dal cgroup in attesa, usare il parametro blkio.group_wait_time.
  • se il dispositivo presenta un queue_depth > 1, il tempo riportato include solo il tempo necessario per l'invio della richiesta al dispositivo e non il tempo d'attesa per il servizio mentre il dispositivo riordina le richieste.
Le voci sono quattro campi:maggiore, minore, operazione e tempo. Maggiore e minore corrispondono ai tipi di dispositivo ed ai numeri di nodo specificati in Linux Allocated Devices, operazione rappresenta il tipo di operazione (read, write, sync, o async) e tempo è la durata del periodo in nanosecondi (ns). Il periodo è riportato in nanosecondi piuttosto che in unità maggiori, cosicché questo report è significativo anche per dispositivi a stato solido.
blkio.io_merged
notifica il numero di richieste di BIOS sommate alle richieste di I/O di un cgroup. Le voci presentano due campi: numero e operazione. Numero rappresenta il numero di richieste e operazione rappresenta il tipo di operazione (read, write, sync, o async).
blkio.io_queued
notifica il numero di richieste in coda per le operazioni di I/O di un cgroup. Le voci presentano due campi: numero e operazione. Numero rappresenta il numero di richieste e operazione rappresenta il tipo di operazione (read, write, sync, o async).
blkio.avg_queue_size
notifica la dimensione media della coda per operazioni di I/O di un cgroup, durante l'esistenza di un gruppo. La dimensione della coda viene campionata ogni qualvolta una coda del cgroup riceve una porzione di tempo. Questo riporto è disponibile solo se CONFIG_DEBUG_BLK_CGROUP=y è stato impostato nel sistema.
blkio.group_wait_time
notifica il tempo totale (in nanosecondi — ns) trascorso da un cgroup in attesa di una porzione di tempo per una delle sue code. Il riporto viene aggiornato ogni qualvolta una coda del cgroup riceve una porzione di tempo, per questo motivo se si esegue una lettura dello pseudofile durante l'attesa del cgroup per una porzione di tempo, il riporto non conterrà il tempo trascorso in attesa per l'operazione messa in coda. Da notare che questo riporto è disponibile solo se CONFIG_DEBUG_BLK_CGROUP=y è stato impostato nel sistema.
blkio.empty_time
notifica il tempo totale (in nanosecondi— ns) trascorso da un cgroup senza alcuna richiesta in attesa. Il riporto viene aggiornato ogni qualvolta una coda per questo cgroup presenta una richiesta in attesa, per questo motivo se si esegue una lettura del pseudofile senza richieste in attesa, il riporto non conterrà il tempo trascorso nello stato corrente. Da notare che questo riporto è disponibile solo se CONFIG_DEBUG_BLK_CGROUP=y è stato impostato nel sistema.
blkio.idle_time
notifica il tempo totale (in nanosecondi — ns) trascorso dallo scheduler con uno stato inattivo per un cgroup in attesa di una richiesta migliore rispetto alle richieste già presenti in altre code o da altri gruppi. Il riporto viene aggiornato ogni qualvolta il gruppo non presenta uno stato inattivo, per questo motivo se si esegue una lettura del pseudofile in presenza di uno stato inattivo il riporto non conterrà il tempo trascorso nello stato inattivo corrente. Questo riporto è disponibile solo se CONFIG_DEBUG_BLK_CGROUP=y è stato impostato nel sistema.
blkio.dequeue
notifica il numero di volte che le richieste di operazioni I/O eseguite da cgroup sono state rimosse dalla coda da parte di dispositivi specifici. Le voci presentano tre campi: maggiore, minore, e numero. Maggiore e minore corrispondono ai tipi di dispositivo ed ai numeri di nodo specificati in Linux Allocated Devices, e numero è il numero di richieste rimosse dalla coda. Questa notifica è disponibile solo se CONFIG_DEBUG_BLK_CGROUP=y è stato impostato nel sistema.

3.1.2. Opzioni di configurazione di I/O Throttling

blkio.throttle.read_bps_device
specifica il limite superiore delle operazioni di lettura che un dispositivo può effettuare. Il tasso di operazioni di lettura è specificato in byte per secondo. Le voci hanno tre campi: maggiore, minore, e byte_per_secondo. Maggiore e minore corrispondono ai tipi di dispositivo ed ai numeri di nodo specificati in Linux Allocated Devices, e byte_per_secondo è il limite superiore del tasso di lettura effettuate dal sistema. Per esempio, per consentire al dispositivo /dev/sda di effettuare operazioni di lettura ad un massimo di 10MBps, eseguire:
~]# echo "8:0 10485760" > /cgroups/blkio/test/blkio.throttle.read_bps_device
blkio.throttle.read_iops_device
specifica il limite superiore delle operazioni di lettura che un dispositivo può effettuare. Il tasso di lettura è specificato in operazioni per secondo. Le voci hanno tre campi: maggiore, minore, e operazioni_per_secondo. Maggiore e minore corrispondono ai tipi di dispositivo ed ai numeri di nodo specificati in Linux Allocated Devices, e operazioni_per_secondo è il limite superiore del tasso di lettura effettuate dal sistema. Per esempio, per consentire al dispositivo /dev/sda di effettuare un massimo di 10 operazioni di lettura per secondo, eseguire:
~]# echo "8:0 10" > /cgroups/blkio/test/blkio.throttle.read_iops_device
blkio.throttle.write_bps_device
specifica il limite superiore delle operazioni di scrittura che un dispositivo può effettuare. Il tasso di operazioni di scrittura è specificato in byte per secondo. Le voci hanno tre campi: maggiore, minore, e byte_per_secondo. Maggiore e minore corrispondono ai tipi di dispositivo ed ai numeri di nodo specificati in Linux Allocated Devices, e byte_per_secondo è il limite superiore del tasso di scrittura effettuate dal sistema. Per esempio, per consentire al dispositivo /dev/sda di effettuare operazioni di scrittura ad un massimo di 10MBps, eseguire:
~]# echo "8:0 10485760" > /cgroups/blkio/test/blkio.throttle.write_bps_device
blkio.throttle.write_iops_device
specifica il limite superiore delle operazioni di scrittura che un dispositivo può effettuare. Il tasso di scrittura è specificato in operazioni per secondo. Le voci hanno tre campi: maggiore, minore, e operazioni_per_secondo. Maggiore e minore corrispondono ai tipi di dispositivo ed ai numeri di nodo specificati in Linux Allocated Devices, e operazioni_per_secondo è il limite superiore del tasso di scrittura effettuate dal sistema. Per esempio, per consentire al dispositivo /dev/sda di effettuare un massimo di 10 operazioni di scrittura per secondo, eseguire:
~]# echo "8:0 10" > /cgroups/blkio/test/blkio.throttle.write_iops_device
blkio.throttle.io_serviced
specifica il numero di operazioni di I/O effettuate da un cgroup su uno specifico dispositivo, come visto dalla policy di throttling. Le voci presentano quattro campi: maggiore, minore, operazione e numero. Maggiore e minore corrispondono ai tipi di dispositivo ed ai numeri di nodo specificati in Linux Allocated Devices, operazione rappresenta il tipo di operazione (read, write, sync, o async) e numero rappresenta il numero di operazioni.
blkio.throttle.io_service_bytes
notifica il numero di byte trasferiti da/verso dispositivi specifici di un cgroup. L'unica differenza tra blkio.io_service_bytes e blkio.throttle.io_service_bytes è che il primo non viene aggiornato quando lo schedulatore CFQ è in esecuzione su una coda di richieste. Le voci hanno quattro campi: maggiore, minore, operazione e byte. Maggiore e minore corrispondono ai tipi di dispositivo ed ai numeri di nodo specificati in Linux Allocated Devices, operazione rappresenta il tipo di operazione (read, write, sync, o async) e byte è il numero di byte trasferiti.

3.1.3. Comuni opzioni di configurazione

La seguente opzione di configurazione può essere usata per qualunque delle policy elencate nella Sezione 3.1, «blkio».
blkio.reset_stats
resetta le statistiche registrate in altri pseudofile. Scrive un valore intero su questo file resettando le statistiche di questo cgroup.

3.1.4. Esempio d'uso

Fare riferimento all'Esempio 3.1, «blkio proportional weight division» per un semplice test di esecuzione di due thread dd in due diversi cgroup con vari valori di blkio.weight.
Esempio 3.1. blkio proportional weight division
  1. Montare il sottosistema blkio:
    ~]# mount -t cgroup -o blkio blkio /cgroup/blkio/
    
  2. Creare due cgroup per il sottosistema blkio
    ~]# mkdir /cgroup/blkio/test1/
    ~]# mkdir /cgroup/blkio/test2/
    
  3. Impostare alcuni pesi di blkio nei cgroup precedentemente creati:
    ~]# echo 1000 > /cgroup/blkio/test1/blkio.weight
    ~]# echo 500 > /cgroup/blkio/test2/blkio.weight
    
  4. Creare due grandi file:
    ~]# dd if=/dev/zero of=file_1 bs=1M count=4000
    ~]# dd if=/dev/zero of=file_2 bs=1M count=4000
    
    I precedenti comandi creano due file (file_1 e file_2) di 4 GB.
  5. Per ciascun cgroup di test, eseguire il comando dd (che legge i contenuti di un file e trasferisce l'output sul dispositivo null), su ognuno dei file:
    ~]# cgexec -g blkio:test1 time dd if=file_1 of=/dev/null
    ~]# cgexec -g blkio:test2 time dd if=file_2 of=/dev/null
    
    Entrambi i comandi, una volta completati, visualizzeranno il tempo di esecuzione.
  6. In contemporanea ai due comandi dd in esecuzione, è possibile monitorare in tempo reale, le prestazioni, usando lo strumento iotop. Per installare lo strumento iotop, eseguire come root il comando yum install iotop. Di seguito, si riporta un esempio di output come visualizzato con lo strumento iotop, durante l'esecuzione dei comandi dd:
    Total DISK READ: 83.16 M/s | Total DISK WRITE: 0.00 B/s
        TIME  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN      IO    COMMAND
    15:18:04 15071 be/4 root       27.64 M/s    0.00 B/s  0.00 % 92.30 % dd if=file_2 of=/dev/null
    15:18:04 15069 be/4 root       55.52 M/s    0.00 B/s  0.00 % 88.48 % dd if=file_1 of=/dev/null
    

Per un risultato più preciso in Esempio 3.1, «blkio proportional weight division», prima di eseguire i comandi dd, svuotare tutti i buffer di file system e liberare pagecache, dentry ed inode usando i seguenti comandi:
~]# sync
~]# echo 3 > /proc/sys/vm/drop_caches
Inoltre, si può abilitare il group isolation che fornisce una maggiore isolazione tra gruppi a spese della latenza. Quando il group isolation è disabilitato, l'equilibrio è raggiunto solo con carichi sequenziali. Per impostazione predefinita, il group isolation è abilitato e l'equilibrio può essere atteso anche con carichi di I/O random. Per abilitare il group isolation, usare il seguente comando:
~]# echo 1 > /sys/block/<dispositivo_disco>/queue/iosched/group_isolation
dove <dispositivo_disco> rappresenta il nome del dispositivo desiderato, per esempio sda.