Red Hat Training

A Red Hat training course is available for Red Hat Enterprise Linux

6.4. Configurazione

Una delle prime decisioni da prendere è il tipo di scheduler I/O da usare. Questa sezione fornisce una panoramica su ogni scheduler per assistere l'utente ad implementare quello più idoneo al carico di lavoro desiderato.

6.4.1. Completely Fair Queuing (CFQ)

Il CFQ cerca di essere il più imparziale possibile nelle decisioni di programmazione dell'I/O prendendo in considerazione il processo che ha iniziato l'I/O. Sono disponibili tre tipi di classi di programmazione: real-time (RT), best-effort (BE), e idle. È possibile assegnare manualmente una classe di programmazione ad un processo tramite il comando ionice o attraverso la chiamata del sistema ioprio_set. Per impostazione predefinita i processi vengono posizionati nella classe best-effort (BE). Le classi real-time (RT) e best-effort vengono suddivise in otto priorità I/O all'interno di ogni classe, con una priorità 0 corrispondente al valore più alto e 7 a quello più basso. I processi nella classe real-time vengono programmati in modo più aggressivo rispetto a quelli presenti in best-effort o idle, per questo motivo ogni I/O real-time programmato viene sempre eseguito prima della classe best-effort o idle. Ciò significa che la priorità real-time può annullare sia la classe best-effort che idle. La classe di programmazione Best effort è quella predefinita e 4 è la priorità di default. I processi nella classe idle vengono serviti solo quando non vi è alcun I/O in attesa nel sistema. Per questo è importante impostare solo la classe di programmazione di un processo su idle se l'I/O non è necessario per procedere con il normale funzionamento.
CFQ garantisce una imparzialità fornendo un periodo di tempo ad ogni processo che esegue un I/O. Durante questo periodo un processo può avere (per impostazione predefinita) fino a 8 richieste per volta. Uno scheduler cercherà di anticipare se una applicazione emetterà un numero maggiore di I/O prendendo in considerazione gli eventi passati. Se è previsto che un processo emetterà un numero maggiore di I/O, CFQ assumerà uno stato di attesa per l'I/O specifico anche se altri I/O sono in attesa di essere emessi.
A causa della sospensione eseguita da CFQ, questa impostazione non sempre risulta essere la più idonea per hardware senza problemi molto grossi di ricerca, come ad esempio array di storage esterni o dischi di tipo solid state. Se è necessario utilizzare CFQ su storage simili (per esempio, se desiderate anche utilizzare il cgroup proportional weight I/O scheduler), sarà necessario ottimizzare alcune impostazioni per migliorare le prestazioni di CFQ. Impostare i seguenti parametri nei file con lo stesso nome presenti in /sys/block/device/queue/iosched/:
slice_idle = 0
quantum = 64
group_idle = 1
Quando group_idle viene impostato su 1, sarà ancora possibile il verificarsi di uno stallo degli I/O (per cui lo storage backend non risulta occupato a causa di uno stato inattivo). Tuttavia esso avrà una frequenza ridotta rispetto agli stati di inattività presenti su ogni coda del sistema.
Un CFQ è uno scheduler I/O di tipo non-work-conserving, esso infatti può entrare in sospensione in presenza di richieste in attesa (come affrontato precedentemente). Lo stack di scheduler di tipo non-work-conserving può introdurre una latenza superiore nel percorso I/O. Un esempio di stack simile è l'uso di CFQ sui controller RAID hardware basati sull'host. I controller RAID possono implementare i propri scheduler non-work-conserving , causando così ritardi su due livelli dello stack. Gli scheduler di tipo non-work-conserving operano nel modo migliore in presenza di un flusso elevato di dati sul quale basare le proprie decisione. In presenza di uno stack di questi algoritmi, lo scheduler nella posizione più bassa sarà in grado di vedere solo l'attività passata dallo scheduler posizionato sopra ad esso. Per questo motivo il livello inferiore potrà solo visualizzare un percorso I/O parziale che non rappresenta affatto il carico di lavoro effettivo.

Parametri ottimizzabili

back_seek_max
Le Backward seek sono processi dannosi per le prestazioni in quanto essi possono avere ritardi maggiori nel riposizionamento delle testine rispetto alle forward seek. Tuttavia CFQ è in grado di eseguirle se risultano essere piccole operazioni di ricerca. Questo parametro controlla la distanza massima abilitato dallo scheduler I/O per questo tipo di ricerche. Il valore predefinito è 16 KB.
back_seek_penalty
A causa della scarsa efficienza delle backward seek verrà loro associata una penalità. La penalità risulta essere un moltiplicatore; per esempio, considerate la posizione di una testina del disco su 1024KB. Supponiamo la presenza in coda di due richieste, una in 1008KB e l'altra in 1040KB. Le due richieste sono equidistanti dalla posizione corrente della testina. Tuttavia dopo aver applicato la penalità dovuta alla backward seek (default:2), la richiesta nella seconda posizione si trova ora due volte più vicina rispetto alla prima richiesta. Per questo motivo la testina si muoverà in avanti.
fifo_expire_async
Questo parametro controlla il periodo entro il quale una richiesta (scrittura in buffer) asincrona può non essere servita. Dopo questo periodo (in millisecondi) una richiesta asincrona non servita verrà spostata nell'elenco Invio. L'impostazione predefinita è 250 ms.
fifo_expire_sync
Simile al parametro ifo_expire_async, per richieste sincrone (lettura e scrittura O_DIRECT). Il valore predefinito è 125 ms.
group_idle
Quando impostato, CFQ sarà inattivo sull'ultimo processo che emette un I/O in un cgroup. Impostare questo valore su 1 quando utilizzate i proportional weight I/O cgroup ed impostare slice_idle su 0 (generalmente impostato su storage veloci).
group_isolation
Se group isolation è stato abilitato (su 1), esso fornisce un isolamento più forte tra gruppi a scapito dell'output netto. In generale se group isolation è stato disabilitato, l'imparzialità viene fornita solo per carichi di lavoro sequenziali. Abilitando questo parametro avrete una imparzialità sia per carichi di lavoro randomici che per quelli sequenziali. Il valore predefinito è 0 (disabilitato). Per maggiori informazioni consultate Documentation/cgroups/blkio-controller.txt.
low_latency
Se il parametro low_latency è stato abilitato (impostato su 1), CFQ cerca di fornire un tempo di attesa massimo di 300 ms per ogni processo che emette un I/O su un dispositivo. Questa impostazione assicura una certa imparzialità sull'output netto. Disabilitando questo parametro (impostandolo su 0) verrà ignorata la latenza target, permettendo così ad ogni processo presente nel sistema di ricevere una quota di tempo completa. Per impostazione predefinita Low latency risulta essere abilitato.
quantum
Il quantum controlla il numero di I/O che il CFQ invierà allo storage in un determinato periodo, limitando così la profondità della coda del dispositivo. Per impostazione predefinita questo valore è impostato su 8. Lo storage è in grado di supportare una coda più grande, ma se aumentate il valore del parametro quantum, potrete impattare negativamente sulla latenza in particolare in presenza di una quantità molto elevata di processi di scrittura sequenziali.
slice_async
Questo valore controlla la quantità di tempo assegnata ad ogni processo che emette I/O asincroni (scrittura con buffer). Per impostazione predefinita questo valore è impostato su 40 ms.
slice_idle
Questo valore specifica la quantità di tempo che CFQ deve essere inattivo in attesa di altre richieste. Il valore predefinito in Red Hat Enterprise Linux 6.1, e versioni precedenti, è di 8 ms. Con Red Hat Enterprise Linux 6.2 e versioni più recenti questo valore è di 0. Il valore zero migliora l'output netto di uno storage RAID esterno, rimuovendo tutti gli stati inattivi a livello albero del servizio e coda. Tuttavia questo valore può impattare negativamente sulle prestazioni di storage non-RAID interni poichè esso aumenta il numero generale di ricerche. Per storage non-RAID è consigliato un valore slice_idle maggiore di 0.
slice_sync
Questo valore controlla la quantità di tempo assegnata ad un processo che emette I/O sincroni (scrittura diretta o lettura). Per impostazione predefinita questo valore è impostato su 100 ms.