Come posso utilizzare lo spazio di scambio solo per le emergenze?


41

Ho un laptop Debian (Buster) con 8 GB di RAM e 16 GB di swap. Sto eseguendo un'attività molto lunga. Ciò significa che il mio laptop è stato lasciato acceso negli ultimi sei giorni mentre si fa strada.

Nel fare ciò, periodicamente devo usare il mio laptop come laptop. Questo non dovrebbe essere un problema; l'attività di lunga durata è associata a I / O, funziona attraverso elementi su un disco rigido USB e non richiede molta RAM (<200 MB) o CPU (<4%).

Il problema è che quando torno al mio laptop dopo alcune ore, sarà molto lento e potrebbero essere necessari 30 minuti per tornare alla normalità. Questo è così grave che i monitor di arresto anomalo segnalano che le loro rispettive applicazioni sono bloccate (in particolare le finestre del browser) e che le cose iniziano a bloccarsi in modo errato.

Guardando il monitor di sistema, dei 2,5 GB utilizzati circa la metà viene spostato in swap. Ho confermato che questo è il problema rimuovendo lo spazio di swap ( swapoff /dev/sda8). Se lo lascio senza spazio di scambio, ritorna in vita quasi istantaneamente anche dopo 24 ore. Con lo scambio, è praticamente un mattone per i primi cinque minuti essendo rimasto solo per sei ore. Ho confermato che l'utilizzo della memoria non supera mai i 3 GB anche quando sono assente.

Ho provato a ridurre lo swappiness ( vedi anche: Wikipedia ) ai valori di 10e 0, ma il problema persiste ancora. Sembra che dopo un giorno di inattività il kernel crede che l'intera GUI non sia più necessaria e la cancella dalla RAM (scambiandola su disco). L'attività di lunga durata è leggere un vasto albero di file e leggere ogni file. Quindi potrebbe essere che il kernel sia confuso nel pensare che la memorizzazione nella cache possa aiutare. Ma con una singola scansione di un USB HD da 2 TB con ~ 1 miliardo di nomi di file, una RAM GB aggiuntiva non contribuirà molto alle prestazioni. Questo è un laptop economico con un disco rigido lento. Semplicemente non è in grado di caricare nuovamente i dati nella RAM abbastanza velocemente.

Come posso dire a Linux di usare lo spazio di swap solo in caso di emergenza? Non voglio correre senza scambio. Se succede qualcosa di inaspettato e il sistema operativo improvvisamente ha bisogno di qualche GB in più, allora non voglio che le attività vengano uccise e preferirei iniziare a usare lo swap. Ma al momento, se lascio abilitare lo scambio, il mio laptop non può essere utilizzato quando ne ho bisogno.

La definizione precisa di "emergenza" potrebbe essere oggetto di dibattito. Ma per chiarire cosa intendo: un'emergenza sarebbe quella in cui il sistema è rimasto senza altra opzione che scambiare o uccidere i processi.


Che cos'è un'emergenza? - Devi davvero chiedere? ... Spero che non ti troverai mai in un edificio in fiamme!

Non è possibile per me definire tutto ciò che potrebbe costituire un'emergenza in questa domanda. Ma ad esempio, un'emergenza potrebbe verificarsi quando il kernel è così spinto per la memoria che ha iniziato a uccidere i processi con OOM Killer . Un'emergenza NON è quando il kernel pensa di poter migliorare le prestazioni usando lo scambio.


Modifica finale: ho accettato una risposta che fa esattamente quello che ho chiesto a livello di sistema operativo. I futuri lettori dovrebbero anche prendere nota delle risposte che offrono soluzioni a livello di applicazione.


11
Definire "emergenza" e dire qualcosa su come questo è diverso da qualsiasi situazione ordinaria quando verrebbe utilizzato lo swap.
Kusalananda

4
Volevo sapere se si voleva in qualche modo definire un tipo speciale di "evento di emergenza" fuori dai limiti che avrebbe permesso al kernel di usare lo swap, ma che altrimenti non sarebbe stato usato. La memoria di paging di AFAIK è qualcosa che è lento e comunque sempre "in caso di emergenza", e la cosa "swappiness" è l'unica cosa con cui sei in grado di adattare questo comportamento (ma non sono un utente Linux).
Kusalananda

2
No, non è corretto. Non è fatto solo in caso di emergenza. Per lo meno ho pensato che la mia domanda chiarisse che ho usato solo 3 GB su 8 GB ... Non è certo un'emergenza ma il kernel si sta comunque scambiando. Ti suggerisco di leggere su swappiness e argomenti circostanti. C'è un bel po 'di discussione sui vari motivi per lo scambio. È plausibile che sto chiedendo un concetto che non esiste nel kernel, ma le mie ragioni per chiederlo sono ragionevolmente ben giustificate ..
Philip Couling

4
Riconosco che il consiglio è sempre stato "mai eseguito senza scambio". Ma le dimensioni della memoria hanno velocità di lettura / scrittura ridotte del disco rigido (HDD non SSD), il che significa che lo scambio è sempre più una cattiva idea. Sembra che alcuni credano che 8 GB di RAM + 8 GB di swap eseguiranno 16 GB di RAM + 0 swap. Se lo fa davvero, allora qualcosa non va nel kernel Linux.
Philip Couling

7
@Philip Couling: No, il punto è che 16 GB di RAM + 16 GB di swap supereranno gli 16 GB e 0 di swap, specialmente quando il tuo codice ha bisogno di 17 GB di memoria :-)
jamesqf

Risposte:


11

Avere uno scambio così grande al giorno d'oggi è spesso una cattiva idea. Quando il sistema operativo ha scambiato solo pochi GB di memoria per scambiare, il tuo sistema era già strisciato a morte (come quello che hai visto)

È meglio utilizzare zramcon una piccola partizione di scambio di backup . Molti sistemi operativi come ChromeOS, Android e varie distribuzioni Linux hanno abilitato zram per impostazione predefinita per anni, in particolare per i sistemi con meno RAM. È molto più veloce dello scambio su HDD e in questo caso puoi chiaramente sentire la reattività del sistema. Meno su un SSD, ma secondo i risultati del benchmark qui sembra ancora più veloce anche con l'algoritmo lzo predefinito. Puoi passare a lz4 per prestazioni ancora migliori con un rapporto di compressione leggermente inferiore. La sua velocità di decodifica è quasi 5 volte più veloce di lzo in base al benchmark ufficiale

C'è anche anche zswapse non l'ho mai usato. Probabilmente vale la pena provare e confrontare quale è meglio per i tuoi casi d'uso

Dopodiché un altro suggerimento è quello di ridurre la priorità di quei processi IO -bound e possibilmente lasciare un terminale in esecuzione con priorità più alta in modo da poter eseguire immediatamente i comandi su di esso anche quando il sistema è carico

Ulteriori letture


Solo per capire, stai dicendo che posso creare un zramdispositivo a blocchi, usarlo come swap, con uno scambio a priorità inferiore come la partizione HDD?
Philip Couling,

@PhilipCouling se usi l'HDD, sì, sicuramente dovresti usare uno zram o soluzioni simili. La priorità dello swap dovrebbe essere inferiore a zram, in modo che Linux provi a utilizzare prima lo zram, quindi prenderà in considerazione lo swap. Se usi Ubuntu, il pacchetto zram-config si occupa già delle impostazioni di priorità per te
phuclv

3
Accetto questa risposta perché sembra fare esattamente quello che ho chiesto. Se ho ancora il mio 16 GB di swap abilitato con una priorità ridotta, il kernel lo userà solo quando zswap è stato esaurito. IE: "in caso di emergenza". Nota su debian-buster questo è molto facile da configurare, semplicemente installando zram-tools.
Philip Couling,

25

Una correzione è assicurarsi che il controller del cgroup di memoria sia abilitato (penso che sia di default anche in kernel semi-recenti, altrimenti dovrai aggiungere cgroup_enable=memoryalla riga di comando del kernel). Quindi è possibile eseguire l'attività intensiva di I / O in un cgroup con un limite di memoria, che limita anche la quantità di cache che può consumare.

Se stai usando systemd, puoi impostare +MemoryAccounting=yese MemoryHigh/ MemoryMaxo MemoryLimit(dipende da se stai usando cgroup v1 o v2) nell'unità, o una slice che lo contiene. Se è una sezione, è possibile utilizzare systemd-runper eseguire il programma nella sezione.

Esempio completo da uno dei miei sistemi per l'esecuzione di Firefox con un limite di memoria. Nota che utilizza cgroups v2 ed è impostato come mio utente, non root (uno dei vantaggi di v2 su v1 è che delegare questo a non-root è sicuro, quindi lo fa systemd).

$ systemctl --user cat mozilla.slice 
# /home/anthony/.config/systemd/user/mozilla.slice
[Unit]
Description=Slice for Mozilla apps
Before=slices.target

[Slice]
MemoryAccounting=yes
MemoryHigh=5G
MemoryMax=6G

$ systemd-run --user --slice mozilla.slice --scope -- /usr/bin/firefox &
$ systemd-run --user --slice mozilla.slice --scope -- /usr/bin/thunderbird &

Ho trovato per far funzionare l'utente uno che ho dovuto usare una fetta. System one funziona semplicemente inserendo le opzioni nel file di servizio (o usando systemctl set-propertysul servizio).

Ecco un servizio di esempio (usando cgroup v1), nota le ultime due righe. Questo fa parte dell'istanza di sistema (pid = 1).

[Unit]
Description=mount S3QL filesystem
Requires=network-online.target
After=network-online.target

[Install]
WantedBy=multi-user.target

[Service]
Type=forking
User=s3ql-user
Group=s3ql-user
LimitNOFILE=20000
ExecStartPre=+/bin/sh -c 'printf "S3QL_CACHE_SIZE=%%i\n" $(stat -c "%%a*%%S*.90/1024" -f /srv/s3ql-cache/ | bc) > /run/local-s3ql-env'
ExecStartPre=/usr/bin/fsck.s3ql  --cachedir /srv/s3ql-cache/fs1 --authfile /etc/s3ql-authinfo  --log none «REDACTED»
EnvironmentFile=-/run/local-s3ql-env
ExecStart=/usr/bin/mount.s3ql --keep-cache --cachedir /srv/s3ql-cache/fs1 --authfile /etc/s3ql-authinfo --cachesize ${S3QL_CACHE_SIZE} --threads 4
ExecStop=/usr/bin/umount.s3ql /mnt/S3QL/
TimeoutStopSec=2m
MemoryAccounting=yes
MemoryLimit=1G

La documentazione è in systemd.resource-control(5).


1
Non puoi fare qualcosa di paragonabile e portatile semplicemente usando ulimit?
Vecchio professionista

1
@OldPro non proprio. Innanzitutto, non c'è AFAIK un ulimit sull'utilizzo totale della memoria, inclusa la cache della pagina (che è l'uso che qui sta diventando eccessivo). In secondo luogo, ulimit per la memoria è per processo, i cgroups funzionano anche se le attività a esecuzione prolungata vengono elaborate.
derobert il

Ho pensato che il motivo per cui l'account di memoria è abilitato per impostazione predefinita sui sistemi più recenti è dovuto a una modifica della systemdversione 238 .
Fontejedi

1
@sourcejedi è relativamente recente. Quando il controller di memoria è stato introdotto per la prima volta, il solo fatto di averlo disponibile (nemmeno in uso) aveva un costo delle prestazioni abbastanza grande che alcune distro lo disabilitavano almeno per impostazione predefinita e si doveva passare l'argomento della riga di comando del kernel per abilitarlo. I problemi di prestazioni sono stati risolti, quindi sono cambiati, e più recentemente anche systemd lo attiva per impostazione predefinita.
derobert l'

14

Sembra che dopo un giorno di inattività il kernel crede che l'intera GUI non sia più necessaria e la cancella dalla RAM (scambiandola su disco).

Il kernel sta facendo The Right Thing ™ credendolo. Perché dovrebbe conservare 1 memoria inutilizzata nella RAM e quindi essenzialmente sprecarla invece di usarla come cache o qualcosa del genere?

Non penso che il kernel Linux stia scambiando pagine gratuitamente o in anticipo, quindi se lo fa deve essere quello di archiviare qualcos'altro sulla RAM, migliorando così le prestazioni del tuo compito di lunga durata, o almeno con questo obiettivo.

Se sai quando dovrai riutilizzare il tuo laptop in anticipo, potresti usare il atcomando (o crontab) per pianificare una pulizia dello swap ( swapoff -a;swapon -a).

Poiché la pulizia dello swap potrebbe essere eccessiva e persino innescare il killer OOM se per qualche motivo, non tutto si adatta alla RAM, potresti semplicemente "annullare lo scambio" 2 tutto ciò che riguarda le applicazioni in esecuzione che desideri ripristinare.

Un modo per farlo sarebbe quello di collegare un debugger come gdba ciascuno dei processi interessati e innescare una generazione di core dump:

# gdb -p <pid>
...
generate-core-dump /dev/null
...
quit

Come hai scritto, la tua applicazione di lunga durata non sta riutilizzando i dati che legge dopo il passaggio iniziale, quindi sei in un caso specifico in cui la memorizzazione nella cache a lungo termine non è utile. Quindi aggirare la cache usando l'I / O diretto come suggerito da Will Crawford dovrebbe essere una buona soluzione.

In alternativa, potresti semplicemente svuotare regolarmente la cache dei file facendo eco 1o 3allo /proc/sys/vm/drop_cachespseudo-file prima che il sistema operativo pensi che sia una buona idea scambiare le applicazioni e l'ambiente della GUI.

Vedi Come svuoti i buffer e la cache su un sistema Linux? per dettagli.

1 Inutilizzato nel senso: non più utilizzato attivamente da un periodo di tempo significativo, la memoria è ancora rilevante per i suoi proprietari.
2 Riposizionare le pagine RAM memorizzate nell'area di scambio.


2
Grazie per il pensiero sulle possibili cause. Ho aggiunto un po 'alla domanda poiché potrebbe essere pertinente. Mi chiedo se c'è un modo per ridurre la priorità della memorizzazione nella cache della memoria dell'applicazione.
Philip Couling

5
"Non credo che il kernel Linux stia scambiando pagine gratuitamente o in anticipo, quindi se lo fa, deve essere quello di memorizzare qualcos'altro sulla RAM, migliorando così le prestazioni." - Penso che questa formulazione sia un po 'ambigua. Il kernel scriverà sicuramente pagine da scambiare, ogni volta che ne ha la possibilità (ad esempio c'è un piccolo I / O su disco). Tuttavia, non li rimuoverà dalla RAM. In questo modo, hai il meglio di entrambi i mondi: se hai rapidamente bisogno di quelle pagine, sono già nella RAM e non c'è niente da fare. Se si verifica un'emergenza (come afferma l'OP), è sufficiente liberare quelle pagine nella RAM, perché
Jörg W Mittag

3
... sono già in scambio. Ed è proprio per questo che non si desidera utilizzare lo swap "solo in caso di emergenza", perché durante un'emergenza il sistema è già sotto stress e l'ultima cosa che si desidera è aggiungere grandi quantità di I / O del disco.
Jörg W Mittag,

2
La cosa che lo fa cambiare è probabilmente il lungo processo: sta accedendo ai file su disco. Quei file in memoria saranno stati usati più di recente rispetto alla memoria della GUI.
jpmc26

3
@ JörgWMittag Hai prove del kernel di Linux, quando l'utilizzo degli I / O è basso, scrivendo preventivamente le pagine nell'area di swap "per ogni evenienza", cioè senza liberarle dalla RAM?
jlliagre,

10

Il processo che stai eseguendo è qualcosa che hai creato tu stesso?

In tal caso, potrebbe essere utile modificare il codice per aprire i file utilizzando il O_DIRECTflag, che per citare la pagina del manuale -

Prova a ridurre al minimo gli effetti cache dell'I / O verso e da questo file. In generale ciò peggiorerà le prestazioni, ma è utile in situazioni speciali, come quando le applicazioni eseguono la propria memorizzazione nella cache. L'I / O dei file viene eseguito direttamente da / verso i buffer dello spazio utente. Il flag O_DIRECT da solo fa uno sforzo per trasferire i dati in modo sincrono, ma non fornisce le garanzie del flag O_SYNC che i dati e i metadati necessari vengono trasferiti. Per garantire l'I / O sincrono, è necessario utilizzare O_SYNC oltre a O_DIRECT. Vedi le NOTE di seguito per ulteriori discussioni.


1
Un altro simile (ma probabilmente più semplice, dato che sono abbastanza sicuro che O_DIRECT abbia restrizioni di allineamento e che ucciderai le prestazioni se le tue letture non sono grandi) è fadvise per dire al kernel che non avrai più bisogno di quei dati, cancellandoli dal cache della pagina. (al telefono o fornirebbe link, mi dispiace)
derobert il

1
@derobert Per uno, il nocachecomando è un trucco conveniente per farlo. (Utilizza LD_PRELOAD per dirottare alcune chiamate libc).
sourcejedi

6

Ecco un'idea, che non ho provato da solo (e mi dispiace non aver avuto il tempo di sperimentare in questo momento).

Supponiamo che tu crei una piccola VM con solo 512 MB di memoria per il tuo processo in background. Non sono sicuro che tu voglia che questo abbia uno swap, una chiamata e disattivi lo swap sul tuo sistema host.


3

Rimuovere lo swap o ridurlo di circa il 20% ( può variare con i sistemi ) in quanto recentemente i sistemi operativi non utilizzano più lo swap allo stesso modo di alcuni anni fa. Probabilmente risponde ad alcune delle tue domande:

-> redhat.com ufficiale

alcune delle informazioni di Red Hat riportate di seguito,

In passato, alcuni fornitori di applicazioni consigliavano scambi di dimensioni pari alla RAM, o addirittura il doppio della RAM. Ora immaginiamo il sistema sopra menzionato con 2 GB di RAM e 2 GB di swap. Un database sul sistema è stato configurato per errore per un sistema con 5 GB di RAM. Una volta esaurita la memoria fisica, viene utilizzato lo swap. Poiché il disco di scambio è molto più lento della RAM, le prestazioni diminuiscono e si verifica il thrashing. A questo punto, anche l'accesso al sistema potrebbe diventare impossibile. Man mano che sempre più memoria viene scritta, alla fine sia la memoria fisica che quella di scambio si esauriscono completamente e il killer OOM entra in azione, uccidendo uno o più processi. Nel nostro caso, è disponibile un sacco di swap, quindi il tempo delle scarse prestazioni è lungo.

e

https://wiki.debian.org/Swap

parte del collegamento Debian sopra,

Informazioni e considerazioni relative alla quantità di swap da utilizzare:

"La quantità raccomandata di spazio di swap è stata tradizionalmente il doppio della quantità di memoria di sistema. Questo è cambiato nel tempo a una volta e mezza la memoria di sistema, entrambe le risposte sono linee di base decenti ma stanno diventando sempre meno utili risposte alla domanda con il passare del tempo. Esistono molte variabili sul tuo sistema e sull'uso previsto che determineranno lo scambio di sistema disponibile che vorrai avere. "

Puoi provare:

"Il modo migliore per disabilitare lo scambio in linux"


Nota personale:


Da quando ho 6 GB di RAM e in tutto il mio recente sistema operativo Linux. Non ho mai visto alcuna indicazione sull'uso di Swap. Ho deciso che devo spegnerlo per spazio (qualche gigabyte in più) e perché a volte ha rallentato il mio sistema.


1
In passato, alcuni fornitori di applicazioni consigliavano scambi di dimensioni pari alla RAM, o addirittura il doppio della RAM. Mi sento molto più vecchio visto che, in qualche modo ... Anche se ho ancora uno degli HDD alla barriera di ~ 528 MB e anche 2,5 GB, in qualche modo quella citazione - beh, è ​​qualcosa di così tanto tempo fa ... Citazione interessante però e potrebbe spiegare perché ho visto problemi simili qualche anno fa. Credo di aver usato sysctl per risolverlo, ma non ricordo esattamente quale impostazione fosse la vigilia.
Pryftan,
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.