Fare in modo che Linux legga lo scambio di nuovo in memoria


28

Il kernel Linux sostituisce la maggior parte delle pagine dalla memoria quando eseguo un'applicazione che utilizza la maggior parte dei 16 GB di memoria fisica. Al termine dell'applicazione, ogni azione (digitazione dei comandi, cambio di aree di lavoro, apertura di una nuova pagina Web, ecc.) Richiede molto tempo per il completamento, poiché le pagine pertinenti devono prima essere lette nuovamente da swap.

C'è un modo per dire al kernel di Linux di copiare le pagine dallo scambio alla memoria fisica senza toccare (e aspettare) manualmente ogni applicazione? Eseguo molte applicazioni quindi l'attesa è sempre dolorosa.

Uso spesso swapoff -a && swapon -aper rendere di nuovo reattivo il sistema, ma questo cancella le pagine dallo scambio, quindi devono essere scritte di nuovo la prossima volta che eseguo lo script.

Esiste un'interfaccia del kernel, forse usando sysfs, per istruire il kernel a leggere tutte le pagine da swap?

Modifica: sto davvero cercando un modo per rendere tutti gli swap scambiati. (Grazie derobert!)

[PS serverfault.com/questions/153946/… e serverfault.com/questions/100448/… sono argomenti correlati ma non affrontano la domanda su come far tornare in memoria il kernel Linux da pagine di swap senza cancellare swap.]


Vuoi che tutto lo swap sia una cache della memoria del sistema? Quindi vuoi un'immagine della memoria del sistema che puoi ricaricare a piacimento? Questo è fondamentalmente il modo in cui funziona l'ibernazione: il sistema immagini la sua memoria su disco, si spegne e ripristina l'immagine all'accensione. C'è qualche possibilità, secondo te, che una query che segue quella discussione possa esserti utile? Ad esempio, se dovessi immaginare la tua memoria, disabilitare lo scambio, completare un'attività, quindi ripristinare l'immagine e ripetere: è qualcosa che ti potrebbe piacere fare?
Mikeserv,

Non penso che questo lascerebbe lo swap in uno stato swapcached. In quanto tale, mi sembra che il tuo suggerimento sia un'alternativa al metodo swapoff-swapon.
drrossum,

No, non memorizza nella cache lo swap (che, a dire il vero , è un po 'strano per me) memorizza nella cache la RAM in un punto che ritieni più integro, quindi dedica l'intera memoria di sistema a un'attività intensa prima di ripristinare la cache quando compito è finito. Se lo scambio durante l'attività intensiva è quello che desideri, rallenterai solo l'attività - avrai bisogno di tempo extra per scambiare le pagine mentre procedi.
Mikeserv,

Risposte:


4

Basato sul programma memdump originariamente trovato qui, ho creato uno script per rileggere selettivamente in memoria le applicazioni specificate. remember:

#!/bin/bash
declare -A Q
for i in "$@"; do
    E=$(readlink /proc/$i/exe);
    if [ -z "$E" ]; then.
        #echo skipped $i;.
        continue;.
    fi
    if echo $E | grep -qF memdump; then.
        #echo skipped $i >&2;.
        continue;.
    fi
    if [ -n "${Q[${E}]}" ]; then.
        #echo already $i >&2;.
        continue;.
    fi
    echo "$i $E" >&2
    memdump $i 2> /dev/null
    Q[$E]=$i
done | pv -c -i 2 > /dev/null

Uso: qualcosa del genere

# ./remember $(< /mnt/cgroup/tasks )
1 /sbin/init
882 /bin/bash
1301 /usr/bin/hexchat
...
2.21GiB 0:00:02 [ 1.1GiB/s] [  <=>     ]
...
6838 /sbin/agetty
11.6GiB 0:00:10 [1.16GiB/s] [      <=> ]
...
23.7GiB 0:00:38 [ 637MiB/s] [   <=>    ]
# 

Salta rapidamente sulla memoria non scambiata (gigabyte al secondo) e rallenta quando è necessario lo scambio.


Questo strumento fa esattamente quello che stavo cercando. Grazie!
drrossum,

Una cosa bella è che, secondo la mia osservazione, le pagine scambiate vengono copiate nella RAM, ma non vengono cancellate dallo scambio (almeno, la maggior parte di esse non lo è, perché l'utilizzo dello scambio diminuisce solo leggermente). La mia interpretazione è che Linux conserva due copie di ogni pagina, una nella RAM e una nello scambio. Se questo viene gestito correttamente, è anche meglio che annullare e aggiungere nuovamente lo swap, perché significa che, quando una doppia pagina dovrà essere scambiata di nuovo, non sarà necessaria un'altra copia. Grazie a qualsiasi esperto del kernel che può confermare.
Giovanni Mascellani,

11

Potrebbe essere d'aiuto /proc/sys/vm/page-cluster(impostazione predefinita: 3).

Dalla documentazione del kernel ( sysctl/vm.txt):

Pagina-cluster

il cluster di pagine controlla il numero di pagine fino a cui le pagine consecutive vengono lette dallo scambio in un solo tentativo. Questa è la controparte dello swap al readahead della cache della pagina. La consecutività menzionata non è in termini di indirizzi virtuali / fisici, ma consecutivi nello spazio di scambio - ciò significa che sono stati scambiati insieme.

È un valore logaritmico: impostandolo su zero significa "1 pagina", impostandolo su 1 significa "2 pagine", impostandolo su 2 significa "4 pagine", ecc. Zero disabilita completamente la lettura dello swap.

Il valore predefinito è tre (otto pagine alla volta). Potrebbero esserci alcuni piccoli vantaggi nell'ottimizzare questo su un valore diverso se il carico di lavoro è ad alta intensità di scambio.

Valori più bassi significano latenze più basse per i guasti iniziali, ma allo stesso tempo guasti aggiuntivi e ritardi I / O per i guasti successivi se fossero stati parte di quelle pagine consecutive che readahead avrebbe portato.

La documentazione non menziona un limite, quindi probabilmente potresti impostare un valore così assurdamente alto da far rileggere tutto lo swap molto presto. E, naturalmente, riportalo in seguito a un valore sano.


Sembra una soluzione utile. I due interventi manuali potrebbero essere combinati con un comando sleep per renderlo un singolo intervento dell'utente. Tuttavia, potrebbe non necessariamente fare in modo che tutti gli swap vengano scambiati molto rapidamente poiché legge solo consecutivamente dalla pagina a cui si accede. Tuttavia, è la soluzione migliore finora. Grazie!
drrossum,

Questa è probabilmente la migliore soluzione che otterrai. Non ne ho mai sentito parlare prima, ma sembra che trasformi lo scambio in una serie di grandi IOP anziché in un insieme continuo di piccoli IOP che è probabilmente ciò che sta causando i tuoi problemi di prestazioni. Sarei legittimamente sorpreso se ci fosse qualcosa che rispondesse perfettamente alla tua situazione individuale.
Bratchley,

In questo caso, se si verificano rallentamenti dovuti a molti piccoli swap in consecutivi, anche solo la regolazione permanente del page-clustervalore su potrebbe migliorare le prestazioni.
Ilmari Karonen,

5

Puoi provare ad aggiungere i programmi a cui tieni di più in un cgroup e ad ottimizzare lo swappiness in modo che la prossima volta che l'applicazione esegue i programmi aggiunti abbia meno probabilità di essere candidati per lo scambio.

Alcune delle loro pagine verranno probabilmente scambiate, ma potrebbero aggirare i problemi di prestazioni. Gran parte di esso è probabilmente solo il comportamento "stop and start" quando molte pagine di un programma sono in scambio e il programma deve continuamente mettere in pausa per scambiare le sue pagine in RAM ma solo con incrementi di 4k.

In alternativa, è possibile aggiungere l'applicazione in esecuzione a un cgroup e ottimizzare lo swappiness in modo che l'applicazione sia quella che tende a utilizzare maggiormente il file di scambio. Rallenterà l'applicazione ma risparmierà il resto del sistema.


4

Mi sembra che non si possa magicamente "rendere di nuovo reattivo il sistema". O incorri nella penalità o rileggi le pagine dallo spazio di scambio nella memoria ora o la incorri in un secondo momento, ma in un modo o nell'altro la incorri. In effetti, se fai qualcosa del genere, swapoff -a && swapon -apotresti provare più dolore piuttosto che meno, perché costringi a copiare alcune pagine in memoria che altrimenti non sarebbero mai state più necessarie e alla fine sono state eliminate senza essere lette (pensa: hai chiuso un'applicazione mentre gran parte del suo mucchio viene sostituito; quelle pagine possono essere scartate del tutto senza mai essere lette in memoria).

ma questo cancella le pagine dallo scambio, quindi devono essere scritte di nuovo la prossima volta che eseguo lo script.

Bene, praticamente ogni pagina che viene copiata indietro dallo swap nella memoria principale sta per essere modificata comunque, quindi se dovesse mai essere spostata indietro per scambiare di nuovo in futuro, dovrebbe comunque essere scritta di nuovo in swap. Tieni presente che lo scambio è principalmente memoria heap, non pagine di sola lettura (che di solito sono supportate da file).

Penso che il tuo swapoff -a && swapon -atrucco sia buono come qualsiasi cosa tu possa inventare.


Siamo in due a dire esattamente la stessa cosa allo stesso tempo;)
Riccioli d'oro

@goldilocks sì, ho visto apparire la tua risposta prima che la mia fosse pronta, ma avevo già ¾ fatto, quindi mi sono bloccato con esso :-)
Celada,

tu e i goldilock dite la stessa cosa, ma non credo che sia così che funziona la cache di swap. La mia comprensione è che puoi avere pagine in swap E memoria allo stesso tempo. La pagina di scambio viene invalidata solo dopo l'aggiornamento della pagina in memoria.
drrossum,

Confido che la risposta a cui fai riferimento David Spillett sia corretta: puoi effettivamente avere una pagina in swap e RAM allo stesso tempo ... ma solo fino a quando la versione RAM non viene modificata. Quindi devi scartare la copia scaduta in swap. Quando ho detto "praticamente ogni pagina che viene copiata dallo swap [...] sta per essere modificata in ogni caso" ciò che intendo è che mi aspetto che sia ciò che accade la maggior parte delle volte, quindi non mi aspetto pagine in entrambi i posti è una frazione significativa di cui vale la pena preoccuparsi.
Celada,

Il tuo scenario di utilizzo potrebbe essere diverso: potresti avere molte applicazioni con grandi cumuli che spesso vengono lette e non scritte. La mia sensazione è che la maggior parte delle persone non abbia uno scenario simile. Ma se lo fai, immagino tu abbia ragione: swapoff -a && swapon -anon ti farà bene. Immagino che in quel caso avresti bisogno di qualcosa che scansiona /proc/<each-process>/meme legge ogni pagina di memoria per assicurarti che esista nella RAM. Non so se esiste.
Celada,

0

C'è una bella discussione qui http://rudd-o.com/en/linux-and-free-software/tales-from-responsivenessland-why-linux-feels-slow-and-how-to-fix-that che si riduce alla riduzione della swappiness, con l'idea che per aumentare la reattività percepita del sistema si dovrebbe impedire di scambiare il codice (e questo è ciò che accade). Questa non è in realtà una risposta alla tua domanda, ma ciò potrebbe impedire la visualizzazione del problema (le tue applicazioni non vengono scambiate, solo dati inutilizzati e cache della pagina)


Sebbene ciò possa teoricamente rispondere alla domanda, sarebbe preferibile includere qui le parti essenziali della risposta e fornire il collegamento come riferimento.
slm
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.