GNU/Linux >> Linux Esercitazione >  >> Linux

Perché il mio sistema Linux balbetta a meno che non elimini continuamente le cache?

Sembra che tu abbia già provato molte delle cose che ti avrei suggerito all'inizio (aggiustare la configurazione dello swap, cambiare gli scheduler di I/O, ecc.).

A parte ciò che hai già provato a modificare, suggerirei di esaminare la modifica delle impostazioni predefinite in qualche modo cerebrali per il comportamento di riscrittura della VM. Questo è gestito dai seguenti sei valori sysctl:

  • vm.dirty_ratio :controlla quante scritture devono essere in sospeso per il writeback prima che venga attivato. Gestisce il writeback in primo piano (per processo) ed è espresso come percentuale intera di RAM. L'impostazione predefinita è il 10% della RAM
  • vm.dirty_background_ratio :controlla quante scritture devono essere in sospeso per il writeback prima che venga attivato. Gestisce il writeback in background (a livello di sistema) ed è espresso come percentuale intera di RAM. L'impostazione predefinita è 20% di RAM
  • vm.dirty_bytes :Uguale a vm.dirty_ratio , eccetto espresso come numero totale di byte. O questo o vm.dirty_ratio verrà utilizzato, qualunque sia stato scritto per ultimo.
  • vm.dirty_background_bytes :Uguale a vm.dirty_background_ratio , eccetto espresso come numero totale di byte. O questo o vm.dirty_background_ratio verrà utilizzato, qualunque sia stato scritto per ultimo.
  • vm.dirty_expire_centisecs :Quanti centesimi di secondo devono trascorrere prima che inizi il writeback in attesa quando i quattro valori sysctl precedenti non lo attiverebbero già. Il valore predefinito è 100 (un secondo).
  • vm.dirty_writeback_centisecs :Quanto spesso (in centesimi di secondo) il kernel valuterà le pagine sporche per il writeback. Il valore predefinito è 10 (un decimo di secondo).

Quindi, con i valori predefiniti, ogni decimo di secondo, il kernel farà quanto segue:

  • Scrivi tutte le pagine modificate nella memoria permanente se sono state modificate l'ultima volta più di un secondo fa.
  • Scrivi tutte le pagine modificate per un processo se la quantità totale di memoria modificata che non è stata scritta supera il 10% della RAM.
  • Scrivi tutte le pagine modificate nel sistema se la quantità totale di memoria modificata che non è stata scritta supera il 20% della RAM.

Quindi, dovrebbe essere abbastanza facile capire perché i valori predefiniti potrebbero causare problemi per te, perché il tuo sistema potrebbe provare a scrivere fino a 4 gigabytes di dati nell'archiviazione permanente ogni decimo di un secondo.

Il consenso generale in questi giorni è di modificare vm.dirty_ratio essere l'1% della RAM e vm.dirty_background_ratio essere del 2%, che per i sistemi con meno di circa 64 GB di RAM si traduce in un comportamento equivalente a quello originariamente previsto.

Alcune altre cose da esaminare:

  • Prova ad aumentare vm.vfs_cache_pressure sysctl un po'. Questo controlla quanto aggressivamente il kernel recupera la memoria dalla cache del filesystem quando ha bisogno di RAM. Il valore predefinito è 100, non abbassarlo a valori inferiori a 50 (farai ottieni un comportamento davvero pessimo se scendi al di sotto di 50, comprese le condizioni OOM) e non aumentarlo a molto più di circa 200 (molto più alto, e il kernel perderà tempo cercando di recuperare memoria che in realtà non può). Ho scoperto che portarlo fino a 150 migliora visibilmente la reattività se disponi di spazio di archiviazione ragionevolmente veloce.
  • Prova a cambiare la modalità di overcommit della memoria. Questo può essere fatto modificando il valore di vm.overcommit_memory sysctl. Per impostazione predefinita, il kernel utilizzerà un approccio euristico per provare a prevedere quanta RAM può effettivamente permettersi di impegnare. L'impostazione di this su 1 disabilita l'euristica e dice al kernel di comportarsi come se avesse una memoria infinita. L'impostazione a 2 dice al kernel di non impegnare più memoria della quantità totale di spazio di swap sul sistema più una percentuale di RAM effettiva (controllata da vm.overcommit_ratio ).
  • Prova a modificare il vm.page-cluster sysctl. Questo controlla quante pagine vengono scambiate dentro o fuori alla volta (è un valore logaritmico in base 2, quindi il valore predefinito di 3 si traduce in 8 pagine). Se stai effettivamente scambiando, questo può aiutare a migliorare le prestazioni dello scambio di pagine dentro e fuori.

Il problema è stato trovato!

Si scopre che si tratta di un problema di prestazioni nel recupero della memoria di Linux quando è presente un numero elevato di contenitori/cgroup di memoria. (Disclaimer:la mia spiegazione potrebbe essere errata, non sono uno sviluppatore del kernel.) Il problema è stato risolto in 4.19-rc1+ in questo set di patch:

Questo patchset risolve il problema con il lento shrink_slab() che si verifica sulle macchine che hanno molti shrinker e cgroup di memoria (cioè, con molti contenitori). Il problema è che la complessità di shrink_slab() è O(n^2) e cresce troppo velocemente con la crescita del numero di contenitori.

Facciamo 200 container, e ogni container ha 10 mount e 10cgroups. Tutte le attività del contenitore sono isolate e non toccano i montaggi dei contenitori esterni.

In caso di recupero globale, un'attività deve iterare su tutti i memcg e chiamare tutti gli strizzacervelli compatibili con memcg per tutti loro. Ciò significa che l'attività deve visitare 200 * 10 =2000 strizzacervelli per ogni memcg, e poiché ci sono 2000 memcg, le chiamate totali di do_shrink_slab() sono 2000 *2000 =4000000.

Il mio sistema è stato colpito particolarmente duramente, poiché eseguo un buon numero di container, che probabilmente era ciò che stava causando la comparsa del problema.

I miei passaggi per la risoluzione dei problemi, nel caso siano utili a chiunque debba affrontare problemi simili:

  1. Nota kswapd0 usando un sacco di CPU quando il mio computer balbetta
  2. Prova a fermare i contenitori Docker e a riempire di nuovo la memoria → il computer non balbetta!
  3. Esegui ftrace (seguendo il magnifico blog di spiegazioni di Julia Evan) per avere una traccia, vedere che kswapd0 tende a rimanere bloccato in shrink_slab , super_cache_count e list_lru_count_one .
  4. Google shrink_slab lru slow , trova il set di patch!
  5. Passa a Linux 4.19-rc3 e verifica che il problema sia stato risolto.

Linux
  1. Cos'è POSIX? Perché è importante per gli utenti Linux/UNIX?

  2. Linux:come si riavvia Gnome senza privilegi di root?

  3. Linux:perché non è presente alcun file system Rootfs sul sistema?

  4. Linux:perché Linux consente "init=/bin/bash"?

  5. Linux – Perché Setuid non funziona??

Linux:perché ci vuole così tanto tempo per rilevare una chiavetta USB?

Il problema della mandria tonante esiste più su Linux?

Perché Ctrl + V non incolla in Bash (shell Linux)?

Perché Linux riscalda il mio computer?

In che modo Linux utilizza un orologio in tempo reale?

Perché un router hardware funziona meglio di un router Linux con specifiche migliori (RAM e CPU)?