Método potencial n. ° 1: F_DROP_CACHES
Encontré un método de 2012 que analiza un parche propuesto para el kernel de Linux en este hilo de correo titulado: Re: [Parche RFC] fs: implementar cachés de caída por archivo .
extracto
Cong> Este es un parche borrador para implementar cachés de caída por archivo.
Interesante. Entonces, ¿puedo hacer esto desde fuera de un proceso? Soy un SysAdmin, por lo que mi POV es notar, encontrar y solucionar problemas de rendimiento cuando el sistema está bajo presión.
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.
¿Cómo puedo saber cuánto caché utiliza un archivo? ¿Y cuál es el impacto en el rendimiento de esto cuando se ejecuta en un sistema ocupado? ¿Y qué nos compra este parche ya que me imagino que la máquina virtual ya debería estar cayendo cachés una vez que el sistema esté bajo presión?
Cong> A continuación se muestra un pequeño caso de prueba para este parche:
El hilo incluye un caso de prueba y el parche real para varios archivos dentro del kernel de Linux que agrega una función adicional al fs/drop_caches.c
llamado drop_pagecache_file(struct file *filp)
. Esta función se puede acceder a través de la herramienta de interfaz, a fnctl.c
través del comando F_DROP_CACHES
. Este caso llama a esta función:
file_drop_caches(filp, arg);
Que maneja la caída de todos los cachés asociados con el archivo dado. Del archivo include/linux/mm.h
:
void file_drop_caches(struct file *filp, unsigned long which);
¿Entonces esto se puede usar?
No encontré evidencia de que este parche haya llegado al repositorio principal de código del kernel de Linux, por lo que esta opción parece estar disponible, solo si está dispuesto a recompilar el kernel de Linux usted mismo.
Método potencial n. ° 2: uso de dd
En ese mismo hilo, otro usuario menciona una metodología completamente diferente que utiliza dd
.
Lo siguiente es un extracto de ese correo electrónico
Esta es una funcionalidad útil. ¿Aunque no está ya provisto
POSIX_FADV_DONTNEED
? Esta funcionalidad se agregó a GNU dd (8.11) hace un año .
Estos son los ejemplos de ese parche:
Aconsejar soltar caché para todo el archivo
$ dd if=ifile iflag=nocache count=0
Asegúrese de soltar el caché para todo el archivo
$ dd of=ofile oflag=nocache conv=notrunc,fdatasync count=0
Caída de caché para parte del archivo
$ dd if=ifile iflag=nocache skip=10 count=10 of=/dev/null
Transmita datos utilizando solo el caché de lectura anticipada
$ dd if=ifile of=ofile iflag=nocache oflag=nocache
Probándolo
No era 100% positivo cómo probar esto, pero se me ocurrió el siguiente enfoque.
hacer un archivo de 100 MB
$ dd if=/dev/urandom of=sample.txt bs=100M count=1
rastrear accesos a archivos usando fatrace
$ sudo fatrace | grep sample.txt
ejecutar top
para que podamos monitorear el uso de memoria, nota cantidad libre.
$ top
Abra el archivo, observe la cantidad de memoria libre ahora. Tenga en cuenta la fatrace
del archivo sample.txt
.
$ cat sample.txt > /dev/null
suelte el archivo de la memoria, observe la cantidad de memoria libre ahora. Tenga en cuenta la salida de fatrace
.
$ sudo dd of=/home/saml/tst/162600/sample.txt \
oflag=nocache conv=notrunc,fdatasync count=0
Ejemplo
En la terminal # 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
En la terminal # 2:
$ top
...
KiB Mem: 7968336 total, 6900956 used, 1067380 free, 267080 buffers
...
En la terminal # 3:
$ sudo fatrace | grep sample.txt
Ahora abra el archivo, sample.txt
y observe la cantidad de RAM. En la terminal # 1.
$ cat sample.txt > /dev/null
En la terminal # 2:
KiB Mem: 7968336 total, 7011896 used, 956440 free, 267336 buffers
Observe la salida de fatrace
en la terminal # 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
Ahora elimine el archivo de RAM, en la terminal # 4:
$ sudo dd of=/home/saml/tst/162600/sample.txt \
oflag=nocache conv=notrunc,fdatasync count=0
Tenga en cuenta la salida de fatrace
en la terminal # 2:
dd(26229): O /home/saml/tst/162600/sample.txt
dd(26229): CW /home/saml/tst/162600/sample.txt
Tenga en cuenta la RAM en la terminal # 3:
KiB Mem: 7968336 total, 6908364 used, 1059972 free, 267364 buffers
Por lo tanto, parece que todo lo que consumió el archivo en RAM se libera.
Método potencial # 3 - python-fadvise
Gracias a un comentario de @frostchutz, hay otra herramienta, un script de Python, [pyadvise][4]
que proporciona una interfaz mucho más simple que los dd
métodos anteriores . Este script hace uso de la misma posix_fadvise(2)
interfaz.
Ejemplo
$ 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
Y si repetimos la prueba anterior y la usamos pyadvise
en lugar de dd
:
$ pyadvise -d /home/saml/tst/162600/sample.txt
Noté una caída idéntica en la RAM que se consumía como antes cuando la usaba dd
.