Metodo potenziale n. 1 - F_DROP_CACHES
Ho trovato un metodo dal 2012 che discute una patch proposta per il kernel Linux in questo thread di posta intitolato: Re: [Patch RFC] fs: implementa cache di rilascio per file .
estratto
Cong> Questa è una bozza di patch per l'implementazione delle cache di rilascio per file.
Interessante. Quindi posso farlo dall'esterno di un processo? Sono un Amministratore di sistema, quindi il mio punto di vista è di notare, trovare e risolvere i problemi di prestazioni quando il sistema è sotto pressione.
Cong> It introduces a new fcntl command F_DROP_CACHES to drop
Cong> file caches of a specific file. The reason is that currently
Cong> we only have a system-wide drop caches interface, it could
Cong> cause system-wide performance down if we drop all page caches
Cong> when we actually want to drop the caches of some huge file.
Come posso sapere quanta cache viene utilizzata da un file? E qual è l'impatto sulle prestazioni di questo quando eseguito su un sistema occupato? E cosa ci offre questa patch dal momento che immagino che la VM dovrebbe già aver lasciato cadere le cache una volta che il sistema è sotto pressione dei mem ...
Cong> Di seguito è riportato un piccolo test case per questa patch:
Il filo include sia un testcase e la patch reale per diversi file all'interno del kernel di Linux che aggiunge una funzione supplementare a fs/drop_caches.c
chiamata drop_pagecache_file(struct file *filp)
. Questa funzione è quindi accessibile tramite lo strumento frontend, fnctl.c
tramite il comando F_DROP_CACHES
. Questo caso chiama questa funzione:
file_drop_caches(filp, arg);
Che gestisce il rilascio di tutte le cache associate al file specificato. Dal file include/linux/mm.h
:
void file_drop_caches(struct file *filp, unsigned long which);
Quindi questo può essere usato?
Non ho trovato prove che questa patch sia mai entrata nel principale repository di codice del kernel Linux, quindi questa opzione sembrerebbe essere disponibile, solo se sei disposto a ricompilare tu stesso il kernel Linux.
Metodo potenziale n. 2 - Utilizzo di dd
Nello stesso thread, un altro utente menziona una metodologia completamente diversa che utilizza dd
.
Quello che segue è estratto da quell'email
Questa è una funzionalità utile. Sebbene non sia già fornito
POSIX_FADV_DONTNEED
? Questa funzionalità è stata aggiunta a GNU dd (8.11) un anno fa .
Ecco gli esempi di quella patch:
Consiglia di eliminare la cache per l'intero file
$ dd if=ifile iflag=nocache count=0
Assicurati di eliminare la cache per l'intero file
$ dd of=ofile oflag=nocache conv=notrunc,fdatasync count=0
Elimina la cache per parte del file
$ dd if=ifile iflag=nocache skip=10 count=10 of=/dev/null
Streaming dei dati utilizzando solo la cache read-ahead
$ dd if=ifile of=ofile iflag=nocache oflag=nocache
Provandolo
Non ero sicuro al 100% su come testarlo, ma ho trovato il seguente approccio.
crea un file da 100 MB
$ dd if=/dev/urandom of=sample.txt bs=100M count=1
tracciare gli accessi ai file usando fatrace
$ sudo fatrace | grep sample.txt
eseguire in top
modo che possiamo monitorare l'utilizzo della memoria, nota quantità gratuita.
$ top
apri il file, nota la quantità di memoria libera ora. Nota fatrace
il file sample.txt
.
$ cat sample.txt > /dev/null
rilascia il file dalla memoria, nota subito la quantità di memoria libera. Nota l'output di fatrace
.
$ sudo dd of=/home/saml/tst/162600/sample.txt \
oflag=nocache conv=notrunc,fdatasync count=0
Esempio
Nel terminale n. 1:
$ dd if=/dev/urandom of=sample.txt bs=100M count=1
1+0 records in
1+0 records out
104857600 bytes (105 MB) copied, 7.37996 s, 14.2 MB/s
$ ls -l sample.txt
-rw-rw-r--. 1 saml saml 104857600 Oct 17 22:54 sample.txt
Nel terminal 2:
$ top
...
KiB Mem: 7968336 total, 6900956 used, 1067380 free, 267080 buffers
...
Nel terminal 3:
$ sudo fatrace | grep sample.txt
Ora apri il file sample.txt
e osserva la quantità di RAM. Nel terminale n. 1.
$ cat sample.txt > /dev/null
Nel terminal 2:
KiB Mem: 7968336 total, 7011896 used, 956440 free, 267336 buffers
Notare l'output del fatrace
terminale n. 3:
cat(25940): R /home/saml/tst/162600/sample.txt
cat(25940): R /home/saml/tst/162600/sample.txt
cat(25940): RC /home/saml/tst/162600/sample.txt
Ora rimuovi il file dalla RAM, nel terminale # 4:
$ sudo dd of=/home/saml/tst/162600/sample.txt \
oflag=nocache conv=notrunc,fdatasync count=0
Notare l'uscita di fatrace
nel terminale # 2:
dd(26229): O /home/saml/tst/162600/sample.txt
dd(26229): CW /home/saml/tst/162600/sample.txt
Notare la RAM nel terminale n. 3:
KiB Mem: 7968336 total, 6908364 used, 1059972 free, 267364 buffers
Quindi sembrerebbe che tutto ciò che è stato consumato dal file nella RAM sia stato liberato.
Metodo potenziale n. 3 - python-fadvise
Grazie a un commento di @frostchutz, c'è un altro strumento, uno script Python, chiamato [pyadvise][4]
che fornisce un'interfaccia molto più semplice rispetto ai dd
metodi di cui sopra . Questo script utilizza la stessa posix_fadvise(2)
interfaccia.
Esempio
$ sudo pyadvise --help
Usage:
pyadvise [options] [FILE]..
Options:
-h, --help show this help message and exit
-w, --willneed The specified files will be accessed in the near future
-s, --sequential The application expects to access the specified files
sequentially (with lower offsets read before higher ones)
-d, --dontneed The specified files will not be accessed in the near
future
-r, --random The specified files will be accessed in random order
-o, --noreuse The specified files will be accessed only once. Under
Linux, this operation is a no-op; see contrib/copyfileobj-
fadvise.py in the python-fadvise source tree for an
example on how to achieve approximately the same effect
-n, --normal Indicates that the application has no advice to give about
its access pattern for the specified files. If no advice
is given for an open file, this is the default assumption
-v, --verbose Explain what is being done
E se ripetiamo il test sopra e utilizziamo pyadvise
al posto di dd
:
$ pyadvise -d /home/saml/tst/162600/sample.txt
Ho notato un calo identico nella RAM consumato come prima quando l'ho usato dd
.