¿Cuáles son las implicaciones de rendimiento para millones de archivos en un sistema de archivos moderno?

30

Digamos que estamos usando ext4 (con dir_index habilitado) para alojar alrededor de 3M de archivos (con un tamaño promedio de 750 KB) y necesitamos decidir qué esquema de carpeta vamos a usar.

En la primera solución , aplicamos una función hash al archivo y usamos una carpeta de dos niveles (siendo 1 carácter para el primer nivel y 2 caracteres para el segundo nivel): por lo tanto, siendo el filex.forhash igual a abcde1234 , lo almacenaremos en / ruta / a / bc /abcde1234-filex.for.

En la segunda solución , aplicamos una función hash al archivo y usamos una carpeta de dos niveles (que son 2 caracteres para el primer nivel y 2 caracteres para el segundo nivel): por lo tanto, siendo el filex.forhash igual a abcde1234 , lo almacenaremos en / ruta / ab / de /abcde1234-filex.for.

Para la primera solución tendremos el siguiente esquema /path/[16 folders]/[256 folders]con un promedio de 732 archivos por carpeta (la última carpeta, donde residirá el archivo).

Mientras que en la segunda solución tendremos /path/[256 folders]/[256 folders]un promedio de 45 archivos por carpeta .

Teniendo en cuenta que vamos a escribir / desvincular / leer archivos ( pero principalmente leídos ) de este esquema mucho (básicamente el sistema de almacenamiento en caché nginx), ¿ importa, en un sentido de rendimiento, si elegimos una u otra solución?

Además, ¿cuáles son las herramientas que podríamos usar para verificar / probar esta configuración?

leandro moreira
fuente
77
Obviamente, la evaluación comparativa ayudará. Pero ext4 puede ser el sistema de archivos incorrecto para esto. Estaría mirando a XFS.
ewwhite
44
No solo miraría XFS, lo usaría de inmediato sin más preámbulos. El árbol B + supera a la tabla hash cada vez.
Michael Hampton
Gracias por los consejos, la evaluación comparativa es un poco difícil, aunque lo intenté, hdparm -Tt /dev/hdXpero podría no ser la herramienta más apropiada.
leandro moreira
2
No, hdparmno es la herramienta adecuada, es una verificación del rendimiento sin procesar del dispositivo de bloque y no una prueba del sistema de archivos.
HBruijn

Respuestas:

28

La razón por la que uno crearía este tipo de estructura de directorios es que los sistemas de archivos deben ubicar un archivo dentro de un directorio, y cuanto más grande sea el directorio, más lenta será esa operación.

Cuánto más lento depende del diseño del sistema de archivos.

El sistema de archivos ext4 utiliza un árbol B para almacenar entradas de directorio. Se espera que una búsqueda en esta tabla tome tiempo O (log n) , que la mayoría de las veces es menor que la tabla lineal ingenua que usaban ext3 y los sistemas de archivos anteriores (y cuando no lo es, el directorio es demasiado pequeño para que pueda realmente importa).

El sistema de archivos XFS utiliza un árbol B + en su lugar. La ventaja de esto sobre una tabla hash o un árbol B es que cualquier nodo puede tener varios hijos b , donde en XFS b varía y puede ser tan alto como 254 (o 19 para el nodo raíz; y estos números pueden estar desactualizados ) Esto le da una complejidad de tiempo de O (log b n) , una gran mejora.

Cualquiera de estos sistemas de archivos puede manejar decenas de miles de archivos en un solo directorio, con XFS siendo significativamente más rápido que ext4 en un directorio con el mismo número de inodes. Pero probablemente no desee un solo directorio con inodos de 3M, ya que incluso con un árbol B + la búsqueda puede llevar algún tiempo. Esto es lo que llevó a crear directorios de esta manera en primer lugar.

En cuanto a sus estructuras propuestas, la primera opción que dio es exactamente lo que se muestra en los ejemplos de nginx. Funcionará bien en cualquiera de los sistemas de archivos, aunque XFS aún tendrá una pequeña ventaja. La segunda opción puede funcionar un poco mejor o un poco peor, pero probablemente estará bastante cerca, incluso en los puntos de referencia.

Michael Hampton
fuente
Y para XFS o ext4, el hardware en el que pones el sistema de archivos tendrá un gran impacto en el rendimiento. Una unidad SATA lenta de 5400 rpm puede realizar aproximadamente 50 operaciones de E / S aleatorias, una buena unidad SAS de 15,000 rpm puede realizar algunos cientos, y una SSD probablemente tendrá un ancho de banda limitado y podría obtener algunos millones de operaciones de E / S aleatorias si no más.
Andrew Henle
1
Estrictamente hablando, $ O (\ log_b n) $ para $ b $ fijo es la misma complejidad que $ O (\ log n) $. Pero para el OP, las constantes reales serían importantes.
Hagen von Eitzen
A menos que haya algún problema con mi sistema de archivos, ext4 no puede manejar 10,000 archivos en un solo directorio. Hacer un simple ls -llleva un minuto completo si el directorio se ha caído del caché de inodo. Y cuando se almacena en caché, todavía lleva más de un segundo. Esto es con un SSD y un Xeon con toneladas de RAM en un servidor web de poco tráfico.
Abhi Beckert
@AbhiBeckert ¿Se actualizó desde ext3? Si es así, intente crear un nuevo directorio y mueva los archivos a él.
Michael Hampton
@Hampton No. es un servidor (bastante) recientemente configurado en hardware moderno. He estado trabajando en el problema con nuestro sysadmin / data center durante un par de meses. Estamos pagando miles de dólares por mes para arrendar el servidor y no estamos obteniendo un rendimiento aceptable. Parece que la única opción es pasar a una nueva estructura de directorio, tal vez usando hashes en lugar de fechas para los nombres de archivo para distribuirlo de manera más uniforme.
Abhi Beckert
5

En mi experiencia, uno de los factores de escala es el tamaño de los inodes dada una estrategia de partición de nombre hash.

Ambas opciones propuestas crean hasta tres entradas de inodo para cada archivo creado. Además, los archivos 732 crearán un inodo que aún es inferior a los 16 KB habituales. Para mí, esto significa que cualquiera de las opciones realizará lo mismo.

Te aplaudo en tu corto hash; Los sistemas anteriores en los que he trabajado han tomado la suma del archivo dado y los directorios empalmados basados ​​en esa cadena, un problema mucho más difícil.

sysadmin1138
fuente
1
¿Qué hace que el uso de sumas SHA1 (y otras sumas hash más largas) sea "un problema mucho más difícil"? Es difícil de manejar para usuarios humanos, sí, pero es lo mismo para el sistema operativo, el sistema de archivos y otros programas.
kbolino
4

Ciertamente, cualquiera de las opciones ayudará a reducir la cantidad de archivos en un directorio a algo que parezca razonable, para xfs o ext4 o cualquier sistema de archivos. No es obvio cuál es mejor, tendría que probarlo para contarlo.

El punto de referencia con su aplicación que simula algo como la carga de trabajo real es ideal. De lo contrario, invente algo que simule muchos archivos pequeños específicamente. Hablando de eso, aquí hay uno de código abierto llamado archivo pequeño . Su documentación hace referencia a algunas otras herramientas.

hdparmhacer E / S sostenidas no es tan útil. No mostrará las muchas E / S pequeñas o entradas de directorio gigantes asociadas con muchos archivos.

John Mahowald
fuente
1

Uno de los problemas es la forma de escanear la carpeta.

Imagine el método Java que ejecuta el escaneo en la carpeta.

Tendrá que asignar una gran cantidad de memoria y desasignarla en un corto período de tiempo, lo cual es muy pesado para la JVM.

La mejor manera es organizar la estructura de carpetas de la manera en que cada archivo está en una carpeta dedicada, por ejemplo, año / mes / día.

La forma en que se realiza el escaneo completo es que para cada carpeta hay una ejecución de la función, por lo que JVM saldrá de la función, desasignará la RAM y la ejecutará nuevamente en otra carpeta.

Esto es solo un ejemplo, pero de todos modos tener una carpeta tan grande no tiene sentido.

Andrew Smith
fuente
2
Estás asumiendo Java y escaneando la carpeta. Tampoco se menciona en la pregunta, y hay otras formas de procesar la carpeta en Java además de escanearla.
user207421
1

He estado teniendo el mismo problema. Intentando almacenar millones de archivos en un servidor Ubuntu en ext4. Terminé ejecutando mis propios puntos de referencia. Descubrí que el directorio plano funciona mucho mejor y es más simple de usar:

punto de referencia

Escribió un artículo .

Hartator
fuente
Ese definitivamente no es el resultado esperado. Antes de continuar con esto o recomendarlo, debe profundizar en por qué obtuvo este resultado inesperado.
Michael Hampton