La traduzione dell'articolo è stata preparata in vista dell'inizio del corso .

Di tanto in tanto sorgono domande sulle raccomandazioni di Gluster riguardo alla configurazione del kernel e se sia necessaria.
Tale necessità si presenta raramente. Nella maggior parte dei casi, il kernel funziona molto bene. Tuttavia, c'è un'altra faccia della medaglia. Storicamente, il kernel di Linux tende a consumare molta memoria se gli viene data l'opportunità, incluso l'uso della cache come principale modalità per migliorare le prestazioni.
In molti casi, questo funziona alla grande, ma sotto carichi elevati potrebbe causare problemi.
Abbiamo una vasta esperienza con sistemi che consumano molta memoria, come CAD, EDA e simili, che hanno iniziato a rallentare sotto carichi pesanti. A volte abbiamo riscontrato problemi con Gluster. Dopo aver monitorato attentamente per diversi giorni la memoria utilizzata e i tempi di attesa dei dischi, abbiamo registrato sovraccarichi, enormi iowait, errori del kernel (kernel oops), blocchi, ecc.
Questo articolo è il risultato di molti esperimenti sull'ottimizzazione delle impostazioni, effettuati in diverse situazioni. Grazie a queste impostazioni, non solo è migliorata la reattività complessiva, ma è anche notevolmente stabilizzata l'attività del cluster.
Quando si tratta di ottimizzare la memoria, è fondamentale esaminare prima il sistema di memoria virtuale (VM, virtual memory), che offre un ampio numero di opzioni che possono confondervi.
vm.swappiness
Caratteristica vm.swappiness definisce quanto il kernel utilizza lo swap rispetto alla memoria RAM. Nel codice sorgente è anche definito come "tendency to steal mapped memory". Un valore elevato di swappiness significa che il kernel sarà più incline a scaricare le pagine mappate. Un valore basso di swappiness significa il contrario: il kernel scaricherà meno le pagine dalla memoria. In altre parole, più alto è il valore vm.swappiness, maggiore sarà l'uso dello swap da parte del sistema.
Un uso intenso dello swapping è sconsigliato, poiché grandi blocchi di dati vengono caricati e scaricati nella memoria. Molti sostengono che il valore di swapiness debba essere alto, ma nella mia esperienza, l'impostazione a '0' porta a un miglioramento delle prestazioni.
Puoi leggere di più qui —
Tuttavia, ancora una volta, queste impostazioni devono essere applicate con cautela e solo dopo aver testato l'applicazione specifica. Per le applicazioni ad alta richiesta di streaming, questo parametro dovrebbe essere impostato su '0'. Modificando il valore a '0', la reattività del sistema migliora.
vm.vfs_cache_pressure
Questo parametro controlla la memoria consumata dal kernel per la cache degli oggetti di directory e dei descrittori di indice (dentry e inode).
Con un valore predefinito di 100, il kernel cercherà di liberare la cache dentry e inode in modo "equo" rispetto a pagecache e swapcache. Ridurre vfs_cache_pressure farà sì che il kernel mantenga le cache dentry e inode. Quando il valore è "0", il kernel non pulirà mai la cache dentry e inode a causa della mancanza di memoria (memory pressure), e questo può facilmente portare a un errore di out-of-memory. Aumentare vfs_cache_pressure oltre 100 porterà il kernel a dare priorità allo scarico di dentry e inode.
Quando si utilizza GlusterFS, molti utenti con grandi volumi di dati e molti piccoli file possono facilmente utilizzare una quantità significativa di memoria sul server a causa della cache di inode/dentry, il che può portare a una riduzione delle prestazioni, poiché il kernel deve elaborare le strutture dati in un sistema con 40 GB di memoria. Impostare questo parametro a oltre 100 ha aiutato molti utenti a ottenere una cache più equa e a migliorare la reattività del kernel.
vm.dirty_background_ratio e vm.dirty_ratio
Il primo parametro (vm.dirty_background_ratio) determina la percentuale di memoria con pagine sporche, al raggiungimento della quale è necessario avviare un flush in background delle pagine sporche su disco. Finché questa percentuale non viene raggiunta, le pagine non vengono scaricate su disco. E quando il flush inizia, avviene in background, senza interrompere i processi in esecuzione.
Il secondo parametro (vm.dirty_ratio) definisce la percentuale di memoria che può essere occupata da pagine sporche prima dell'inizio di un flush forzato. Al raggiungimento di questa soglia, tutti i processi diventano sincroni (bloccati) e non possono continuare a funzionare finché l'operazione di input/output richiesta non è effettivamente completata e i dati non sono scritti su disco. In caso di un carico elevato di operazioni di input/output, ciò provoca un problema, poiché la memorizzazione nella cache dei dati non è disponibile e tutti i processi che eseguono input/output vengono bloccati in attesa di operazioni di input/output. Questo porta a un numero elevato di processi bloccati, alto carico, instabilità del sistema e scarse prestazioni.
Ridurre i valori di questi parametri fa sì che i dati vengano scritti su disco più frequentemente e non venga mantenuta la memoria RAM. Questo può essere utile per sistemi con molta memoria, dove è normale scrivere su disco la cache delle pagine da 45 a 90 GB, il che porta a tempi di attesa elevati per le applicazioni frontend, diminuendo la reattività e l'interattività complessive.
«1» > /proc/sys/vm/pagecache
La cache delle pagine (page cache) è un'area di memoria in cui vengono conservati i dati dei file e dei programmi eseguibili, ovvero sono le pagine con il contenuto reale dei file o dei dispositivi di blocco. Questa cache viene utilizzata per ridurre il numero di letture dal disco. Il valore «1» indica che per la cache viene utilizzato l'1% della RAM e ci saranno più operazioni di lettura dal disco rispetto alla RAM. Non è necessario modificare questo parametro, ma se si è particolarmente attenti al controllo della cache delle pagine, si può usufruire di questa opzione.
«deadline» > /sys/block/sdc/queue/scheduler
Lo scheduler I/O è un componente del kernel Linux che gestisce le code di lettura e scrittura. Teoricamente, per un RAID controller intelligente è meglio utilizzare "noop", perché Linux non conosce la geometria fisica del disco, quindi è più efficiente lasciare che il controller, che conosce bene la geometria del disco, gestisca le richieste il più rapidamente possibile. Tuttavia, sembra che "deadline" aumenti le prestazioni. Puoi leggere di più sugli scheduler nella documentazione del codice sorgente del kernel Linux: linux/Documentation/block/*osched.txt. Ho anche osservato un aumento della larghezza di banda di lettura durante operazioni miste (molte operazioni di scrittura).
"256" > /sys/block/sdc/queue/nr_requests
Il numero di richieste di input/output che vengono messe in buffer prima di essere inviate allo schedule. La dimensione della coda interna di alcuni controller (queue_depth) è maggiore della nr_requests dello scheduler di I/O, quindi lo scheduler ha poche possibilità di dare priorità correttamente e di eseguire la fusione delle richieste. Per gli scheduler deadline e CFQ è preferibile che nr_requests sia il doppio della coda interna del controller. La fusione e la riordino delle richieste aiutano lo scheduler a essere più reattivo sotto carico.
echo «16» > /proc/sys/vm/page-cluster
Il parametro page-cluster gestisce il numero di pagine che vengono scritte nello swap in un colpo solo. Nell'esempio sopra, il valore è impostato a «16» in base alla dimensione del stripe (stripe size) RAID di 64 KB. Non ha senso con swappiness = 0, ma se hai impostato swappiness a 10 o 20, l'utilizzo di questo valore ti aiuterà quando la dimensione del stripe RAID è di 64 KB.
blockdev —setra 4096 /dev/<devname> (-sdb, hdc o dev_mapper)
Le impostazioni predefinite dei dispositivi di archiviazione per molti controller RAID spesso portano a prestazioni disastrose. Aggiungendo l'opzione sopra indicata, si configura la lettura anticipata per settori di 4096 * 512 byte. Almeno per le operazioni di streaming, si aumenta la velocità riempiendo la cache integrata del disco attraverso la lettura anticipata nel periodo in cui il kernel è impegnato a preparare le operazioni di input/output. I dati possono essere memorizzati nella cache e richiesti alla lettura successiva. Una lettura anticipata eccessiva può compromettere l'input/output casuale per file di grandi dimensioni, se sfrutta il tempo utile del disco o carica dati oltre la cache.
Di seguito sono riportati ulteriori suggerimenti a livello di file system. Tuttavia, non sono stati ancora testati. Assicurati che il tuo file system conosca la dimensione dello stripe e il numero di dischi nell'array. Ad esempio, che si tratta di un array raid5 con dimensione dello stripe di 64K composto da sei dischi (effettivamente da cinque, poiché un disco è utilizzato per la parità). Questi consigli sono basati su ipotesi teoriche e raccolti da vari blog/articoli di esperti in RAID.
-> ext4 fs, 5 dischi, 64K stripe, unità in blocchi da 4K
mkfs -text4 -E stride=$((64/4))
-> xfs, 5 dischi, 64K stripe, unità in settori da 512 byte
mkfs -txfs -d sunit=$((64*2)) -d swidth=$((5*64*2))Per file di grandi dimensioni, potresti considerare di aumentare le dimensioni degli stripe sopra indicati.
ATTENZIONE! Tutto ciò che è stato descritto sopra è estremamente soggettivo per alcuni tipi di applicazioni. Questo articolo non garantisce alcun miglioramento senza un test preliminare delle relative applicazioni da parte dell'utente. Dovrebbe essere applicato solo se necessario per migliorare la reattività complessiva del sistema o, se risolve problemi attuali.
Materiale aggiuntivo:
Leggi di più
Fonte: habr.com
