Che cos'è vm.min_free_kbytes e come ottimizzarlo?

What Is Vm Min_free_kbytes



Che cos'è vm.min_free_kbytes sysctl sintonizzabile per il kernel Linux e su quale valore dovrebbe essere impostato? Studieremo questo parametro e come influisce su un sistema Linux in esecuzione in questo articolo. Verificheremo il suo impatto sulla cache della pagina del sistema operativo e su malloc e cosa mostra il comando libero di sistema quando questo parametro è impostato. Faremo alcune ipotesi plausibili sui valori ideali per questo parametro sintonizzabile e mostreremo come impostare vm.min_free_kbytes in modo permanente per sopravvivere ai riavvii. Quindi andiamo.

Come funziona vm.min_free_kbytes

Le allocazioni di memoria possono essere necessarie al sistema per garantire il corretto funzionamento del sistema stesso. Se il kernel consente l'allocazione di tutta la memoria, potrebbe avere difficoltà quando è necessaria la memoria per le operazioni regolari per mantenere il sistema operativo senza intoppi. Ecco perché il kernel fornisce il parametro sintonizzabile vm.min_free_kbytes. Il parametro sintonizzabile forzerà il gestore della memoria del kernel a mantenere almeno X quantità di memoria libera. Ecco la definizione ufficiale dal documentazione del kernel linux Nota: viene utilizzato per forzare la VM Linux a mantenere un numero minimo di kilobyte liberi. La VM usa questo numero per calcolare un valore di watermark[WMARK_MIN] per ogni zona lowmem nel sistema. Ogni zona lowmem ottiene un numero di pagine gratuite riservate in base alla sua dimensione. È necessaria una quantità minima di memoria per soddisfare le allocazioni PF_MEMALLOC; se lo imposti su un valore inferiore a 1024 KB, il tuo sistema si guasterà leggermente e sarà soggetto a deadlock sotto carichi elevati. Impostando questo valore troppo alto, la tua macchina verrà OOM all'istante.







Convalida dei lavori vm.min_free_kbytes

Per verificare che l'impostazione di min_free_kbytes funzioni come previsto, ho creato un'istanza virtuale di Linux con solo 3,75 GB di RAM. Usa il comando gratuito qui sotto per analizzare il sistema:



#gratuito -m



Guardando l'utilità di memoria libera sopra usando il flag -m per avere i valori stampati in MB. La memoria totale va da 3,5 a 3,75 GB di memoria. Vengono utilizzati 121 MB di memoria, 3,3 GB di memoria sono liberi, 251 MB vengono utilizzati dalla cache del buffer. E sono disponibili 3,3 GB di memoria.





Ora cambieremo il valore di vm.min_free_kbytes e vedremo qual è l'impatto sulla memoria di sistema. Faremo eco al nuovo valore nel filesystem virtuale proc per modificare il valore del parametro del kernel come di seguito:

# echo 1500000 > /proc/sys/vm/min_free_kbytes
# sysctl vm.min_free_kbytes



Puoi vedere che il parametro è stato modificato a circa 1,5 GB e ha avuto effetto. Ora usiamo il gratuito nuovamente il comando per vedere eventuali modifiche riconosciute dal sistema.

#gratuito -m

La memoria libera e la cache del buffer sono invariate dal comando, ma la quantità di memoria visualizzata come a disposizione è stato ridotto da 3327 a 1222 MB. Che è una riduzione approssimativa della modifica del parametro a 1,5 GB di memoria libera min.

Ora creiamo un file di dati da 2 GB e poi vediamo cosa fa la lettura di quel file nella cache del buffer sui valori. Ecco come creare un file di dati da 2 GB in 2 righe di script bash di seguito. Lo script genererà un file casuale di 35 MB utilizzando il comando dd e quindi lo copierà 70 volte in un nuovo file di dati produzione:

# dd if=/dev/random of=/root/d1.txt count=1000000
# per i in `seq 1 70`; fai echo $i; cat /root/d1.txt >> /root/file_dati; fatto

Leggiamo il file e ignoriamo il contenuto leggendo e reindirizzando il file a /dev/null come di seguito:

#gattofile di dati> /sviluppo/nullo

Ok, cosa è successo alla nostra memoria di sistema con questo insieme di manovre, controlliamo ora:

#gratuito -m

Analizzando i risultati sopra. Abbiamo ancora 1,8 GB di memoria libera, quindi il kernel ha protetto una grossa fetta di memoria come riservata a causa della nostra impostazione min_free_kbytes. La cache del buffer ha utilizzato 1691 MB, che è inferiore alla dimensione totale del nostro file di dati che è di 2,3 GB. A quanto pare l'intero file di dati non è stato possibile memorizzare nella cache a causa della mancanza di memoria disponibile da utilizzare per la cache del buffer. Possiamo verificare che l'intero file non sia memorizzato nella cache ma cronometrando i ripetuti tentativi di lettura del file. Se è stato memorizzato nella cache, ci vorrebbe una frazione di secondo per leggere il file. Proviamolo.

# time cat data_file > /dev/null
# time cat data_file > /dev/null

La lettura del file ha richiesto quasi 20 secondi, il che implica che quasi certamente non è tutto memorizzato nella cache.

Come ultima convalida, riduciamo vm.min_free_kbytes per consentire alla cache della pagina di avere più spazio per funzionare e possiamo aspettarci di vedere la cache funzionare e la lettura del file diventare molto più veloce.

# echo 67584 > /proc/sys/vm/min_free_kbytes
# time cat data_file > /dev/null
# time cat data_file > /dev/null

Con la memoria extra disponibile per la memorizzazione nella cache, il tempo di lettura del file è sceso da 20 secondi prima a 0,364 secondi con tutto nella cache.

Sono curioso di fare un altro esperimento. Cosa succede con le chiamate malloc per allocare memoria da un programma C a fronte di questa impostazione vm.min_free_kbytes davvero elevata. Fallirà il malloc? Il sistema morirà? Per prima cosa ripristina l'impostazione vm.min_free_kbytes al valore veramente alto per riprendere i nostri esperimenti:

#buttato fuori 1500000 > /per cento/sistema/vm/min_kbyte_liberi

Guardiamo ancora la nostra memoria libera:

In teoria abbiamo 1,9 GB liberi e 515 MB disponibili. Usiamo un programma di stress test chiamato stress-ng per usare un po' di memoria e vedere dove falliamo. Useremo il tester vm e proveremo ad allocare 1 GB di memoria. Dal momento che abbiamo riservato solo 1,5 GB su un sistema da 3,75 GB, immagino che dovrebbe funzionare.

# stress-ng --vm 1 --vm-bytes 1G --timeout 60s
stress: informazioni:[17537]spedizione di maiali:1vm
stress: informazioni:[17537]allocazione della cache: dimensione della cache predefinita: 46080K
stress: informazioni:[17537]corsa riuscita completatain60.09s(1minimo,0.09asciutto)
# stress-ng --vm 2 --vm-bytes 1G --timeout 60s
# stress-ng --vm 3 --vm-bytes 1G --timeout 60s

Riproviamo con più lavoratori, possiamo provare 1, 2, 3, 4 lavoratori e ad un certo punto dovrebbe fallire. Nel mio test è passato con 1 e 2 lavoratori, ma non con 3 lavoratori.

Reimpostare vm.min_free_kbytes su un numero basso e vedere se questo ci aiuta a eseguire 3 stress di memoria con 1 GB ciascuno su un sistema da 3,75 GB.

# echo 67584 > /proc/sys/vm/min_free_kbytes
# stress-ng --vm 3 --vm-bytes 1G --timeout 60s

Questa volta ha funzionato correttamente senza errori, l'ho provato due volte senza problemi. Quindi posso concludere che c'è una differenza comportamentale nell'avere più memoria disponibile per malloc, quando il valore vm.min_free_kbytes è impostato su un valore inferiore.

Impostazione predefinita per vm.min_free_kbytes

Il valore predefinito per l'impostazione sul mio sistema è 67584 che è circa l'1,8% della RAM sul sistema o 64 MB. Per motivi di sicurezza su un sistema pesantemente thrashing, tenderei ad aumentarlo un po' forse a 128 MB per consentire una memoria libera più riservata, tuttavia per un utilizzo medio il valore predefinito sembra abbastanza ragionevole. La documentazione ufficiale avverte di rendere il valore troppo alto. Impostarlo al 5 o al 10% della RAM di sistema probabilmente non è l'uso previsto dell'impostazione ed è troppo alto.

Impostazione di vm.min_free_kbytes per sopravvivere ai riavvii

Per garantire che l'impostazione possa sopravvivere ai riavvii e non venga ripristinata ai valori predefiniti al riavvio, assicurarsi di rendere persistente l'impostazione sysctl inserendo il nuovo valore desiderato nel file /etc/sysctl.conf.

Conclusione

Abbiamo visto che il parametro sintonizzabile del kernel linux vm.min_free_kbytes può essere modificato e può riservare memoria sul sistema per garantire che il sistema sia più stabile, specialmente durante un uso intenso e allocazioni di memoria pesanti. Le impostazioni predefinite potrebbero essere un po' troppo basse, specialmente su sistemi ad alta memoria e dovrebbero essere considerate di essere aumentate con attenzione. Abbiamo visto che la memoria riservata da questo parametro sintonizzabile impedisce alla cache del sistema operativo di utilizzare tutta la memoria e impedisce anche ad alcune operazioni di malloc di utilizzare tutta la memoria.