Linux: ¿cuántas E / S de disco se necesitan para leer un archivo? ¿Cómo minimizarlo? [duplicar]

10

Según este documento en el Haystack de Facebook:

" Debido a cómo los dispositivos NAS administran los metadatos del directorio, colocar miles de archivos en un directorio fue extremadamente ineficiente ya que el mapa de bloques del directorio era demasiado grande para que el dispositivo lo almacenara en caché de manera efectiva. En consecuencia, era común incurrir en más de 10 operaciones de disco para recuperar un imagen única. Después de reducir los tamaños de directorio a cientos de imágenes por directorio, el sistema resultante aún incurriría en 3 operaciones de disco para recuperar una imagen: una para leer los metadatos del directorio en la memoria, un segundo para cargar el inodo en la memoria y un tercero para leer el contenido del archivo " .

Supuse que el sistema operativo siempre almacenaría en la memoria caché los metadatos y el inodo del directorio del sistema de archivos y que la lectura de un archivo generalmente requeriría solo 1 disco IO.

¿Es este problema de "E / S de múltiples discos para leer un solo archivo" descrito en ese documento exclusivo de los dispositivos NAS, o Linux también tiene el mismo problema?

Estoy planeando ejecutar un servidor Linux para servir imágenes. De cualquier manera, puedo minimizar la cantidad de E / S de disco, ¿idealmente asegurándome de que el sistema operativo almacene en caché todos los datos de directorio e inodo en RAM y que cada lectura de archivo solo requiera no más de 1 E / S de disco?

usuario9517
fuente
1
No es una respuesta a la pregunta, pero siempre puedes usar Varnish (Facebook lo usa) que mantiene los archivos en la memoria. De esta manera, si una imagen se calienta (muchas solicitudes para el mismo archivo), el disco IO no se utilizará en absoluto para servirlo
Darhazer: Varnish no ayudaría aquí, ya que el caché de archivos de Linux (en el que se basa Varnish) ya almacena en caché los archivos activos en la memoria. Poner Varnish frente a Nginx para el servicio de archivos estáticos realmente no agrega nada. Mi pregunta es sobre cuándo los archivos son demasiado grandes / demasiados para ser almacenados en la memoria caché. Todavía quiero asegurarme de que al menos los datos de directorio y los inodos estén en caché para reducir la E / S del disco a solo 1 por lectura.
Muchos sistemas de archivos almacenan el inodo dentro del directorio, lo que reduce el número de solicitudes en uno y aumenta significativamente la posibilidad de un golpe de caché. Pero esta no es una pregunta de programación.
Ben Voigt
Puede cambiar el tamaño de bloque del sistema de archivos al crearlo, por ejemplo, con el mke2fs -b 32768fin de hacerlo 32k. Sin embargo, esto es útil solo si no tiene archivos pequeños en ese sistema de archivos.

Respuestas:

5

Linux tiene el mismo "problema". Aquí hay un artículo que un estudiante mío publicó hace dos años, donde el efecto se muestra en Linux. Los múltiples IO pueden provenir de varias fuentes:

  • Búsqueda de directorio en cada nivel de directorio de la ruta del archivo. Puede ser necesario leer el inodo del directorio y uno o más bloques de entrada del directorio
  • Inode del archivo

En el patrón normal de E / S, el almacenamiento en caché es realmente efectivo y los inodos, directorios y bloques de datos se asignan de manera que reducen las búsquedas. Sin embargo, el método de búsqueda normal, que en realidad es compartido por todos los sistemas de archivos, es malo para el tráfico altamente aleatorio.

Aqui hay algunas ideas:

1) Ayuda de cachés relacionadas con el sistema de archivos. Un caché grande absorberá la mayoría de las lecturas. Sin embargo, si desea colocar varios discos en una máquina, la relación Disco-RAM limita la cantidad almacenada en caché.

2) No use millones de archivos pequeños. Agréguelos a archivos más grandes y almacene el nombre de archivo y el desplazamiento dentro del archivo.

3) Coloque o guarde en caché los metadatos en un SSD.

4) Y, por supuesto, use un sistema de archivos que no tenga un formato de directorio en disco totalmente anárquico. Un readdir no debería tomar más que tiempo lineal, y el acceso directo a archivos idealmente solo es tiempo logarítmico.

Mantener directorios pequeños (menos de 1000 aproximadamente) no debería ayudar mucho porque necesitaría más directorios con la necesidad de almacenar en caché.

dmeister
fuente
Y, por supuesto, utilice un sistema de archivos que no tenga un formato de directorio en disco totalmente arcaico. Un readdir no debería tomar más que tiempo lineal, y el acceso directo a archivos idealmente solo es tiempo logarítmico.
jørgensen
Agregué
@dmeister Buenas cosas. +1
Magellan
@dmeister Su enlace está muerto.
Don Scott
1

Esto depende del sistema de archivos que planea usar. Antes de leer el sistema de datos de archivos:

  • Leer el archivo de directorio.
  • Lea el inodo de su archivo
  • Leer sectores del archivo de tu

Si la carpeta contiene una gran cantidad de archivos, esta es una gran preassure en caché.


fuente
Si está enumerando los accesos de E / S, puede ser más interesante separar open()los realizados por read(). La página win.tue.nl/~aeb/linux/vfs/trail.html muestra un buen recorrido por los diferentes conceptos de Kernel involucrados. (¿Tal vez está desactualizado? No podría decirlo)
adl
0

Probablemente no podrá mantener todos los datos de directorio e inodo en RAM, ya que probablemente tenga más datos de directorio e inodo que RAM. Es posible que tampoco desee hacerlo, ya que esa RAM podría utilizarse mejor para otros fines; en su ejemplo de imagen, ¿no preferiría tener los datos de una imagen a la que se accede con frecuencia en caché en la memoria RAM que la entrada del directorio para una imagen a la que se accede con poca frecuencia?

Dicho esto, creo que la perilla vfs_cache_pressure se usa para controlar esto. "Cuando vfs_cache_pressure = 0, el núcleo nunca reclamará dentries e inodos debido a la presión de la memoria y esto puede conducir fácilmente a condiciones de falta de memoria".

Samuel Edwin Ward
fuente