Pregunta

Un producto en el que estoy trabajando recopila varios miles de lecturas por día y las almacena como archivos binarios de 64k en una partición NTFS (Windows XP).Después de un año en producción, hay más de 300.000 archivos en un único directorio y el número sigue creciendo.Esto ha hecho que acceder a los directorios de padres/ancestros desde el Explorador de Windows consuma mucho tiempo.

Intenté desactivar el servicio de indexación pero no hubo diferencia.También he contemplado mover el contenido del archivo a una base de datos/archivos zip/tarballs, pero es beneficioso para nosotros acceder a los archivos individualmente;Básicamente, los archivos todavía son necesarios para fines de investigación y los investigadores no están dispuestos a ocuparse de nada más.

¿Existe alguna forma de optimizar NTFS o Windows para que pueda funcionar con todos estos archivos pequeños?

¿Fue útil?

Solución

El rendimiento de NTFS se degrada gravemente después de 10.000 archivos en un directorio.Lo que debe hacer es crear un nivel adicional en la jerarquía de directorios, donde cada subdirectorio tenga 10.000 archivos.

Por si sirve de algo, este es el enfoque que adoptó la gente de SVN. versión 1.5.Utilizaron 1000 archivos como umbral predeterminado.

Otros consejos

NTFS en realidad funcionará bien con más de 10,000 archivos en un directorio siempre que le indique que deje de crear nombres de archivos alternativos compatibles con plataformas Windows de 16 bits.De forma predeterminada, NTFS crea automáticamente un nombre de archivo de '8 puntos 3' para cada archivo que se crea.Esto se convierte en un problema cuando hay muchos archivos en un directorio porque Windows mira los archivos en el directorio para asegurarse de que el nombre que están creando no esté ya en uso.Puede deshabilitar la denominación '8 punto 3' estableciendo el valor de registro NtfsDisable8dot3NameCreation en 1.El valor se encuentra en la ruta de registro HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\FileSystem.Es seguro realizar este cambio ya que los archivos de nombre '8 punto 3' sólo son necesarios para programas escritos para versiones muy antiguas de Windows.

Es necesario reiniciar antes de que esta configuración surta efecto.

El problema de rendimiento se debe a la gran cantidad de archivos en un solo directorio:una vez que elimines eso, deberías estar bien.Este no es un problema específico de NTFS:de hecho, se encuentra comúnmente con los archivos de inicio/correo de los usuarios en sistemas UNIX grandes.

Una forma obvia de resolver este problema es mover los archivos a carpetas con un nombre basado en el nombre del archivo.Suponiendo que todos sus archivos tengan nombres de archivo de longitud similar, p.ABCDEFGHI.db, ABCEFGHIJ.db, etc., cree una estructura de directorio como esta:

ABC\
    DEF\
        ABCDEFGHI.db
    EFG\
        ABCEFGHIJ.db

Con esta estructura, puede localizar rápidamente un archivo según su nombre.Si los nombres de los archivos tienen longitudes variables, elija una longitud máxima y anteponga ceros (o cualquier otro carácter) para determinar el directorio al que pertenece el archivo.

He visto grandes mejoras en el pasado al dividir los archivos en una jerarquía anidada de directorios, por ejemplo, por la primera y luego la segunda letra del nombre del archivo;entonces cada directorio no contiene una cantidad excesiva de archivos.Sin embargo, la manipulación de toda la base de datos sigue siendo lenta.

Podrías intentar usar algo como Solid File System.

Esto le brinda un sistema de archivos virtual que las aplicaciones pueden montar como si fuera un disco físico.Su aplicación ve muchos archivos pequeños, pero solo uno se encuentra en su disco duro.

http://www.eldos.com/solfsdrv/

Si puede calcular los nombres de los archivos, es posible que pueda ordenarlos en carpetas por fecha, de modo que cada carpeta solo tenga archivos para una fecha particular.Es posible que también desee crear jerarquías de meses y años.

Además, ¿podría mover archivos de más de un año, digamos, a una ubicación diferente (pero aún accesible)?

Finalmente, una vez más, esto requiere que puedas calcular nombres; descubrirás que acceder directamente a un archivo es mucho más rápido que intentar abrirlo a través del explorador.Por ejemplo, diciendo
notepad.exe "P:\ath o u\filen.ame"
desde la línea de comando debería ser bastante rápido, suponiendo que conozca la ruta del archivo que necesita sin tener que obtener una lista de directorio.

Un truco común es simplemente crear un puñado de subdirectorios y dividir los archivos.

Por ejemplo, Doxygen, un programa de documentación de código automatizado que puede producir toneladas de páginas html, tiene una opción para crear una jerarquía de directorios profunda de dos niveles.Luego, los archivos se distribuyen uniformemente en los directorios inferiores.

Tener cientos de miles de archivos en un solo directorio de hecho paralizará NTFS, y realmente no hay mucho que puedas hacer al respecto.Debería reconsiderar el almacenamiento de los datos en un formato más práctico, como un tarball grande o en una base de datos.

Si realmente necesita un archivo separado para cada lectura, debe ordenarlos en varios subdirectorios en lugar de tenerlos todos en el mismo directorio.Puede hacer esto creando una jerarquía de directorios y colocando los archivos en diferentes según el nombre del archivo.De esta manera aún puedes almacenar y cargar tus archivos sabiendo solo el nombre del archivo.

El método que utilizamos es tomar las últimas letras del nombre del archivo, invertirlas y crear directorios de una letra a partir de ahí.Considere los siguientes archivos, por ejemplo:

1.xml
24.xml
12331.xml
2304252.xml

puedes ordenarlos en directorios así:

data/1.xml
data/24.xml
data/1/3/3/12331.xml
data/2/5/2/4/0/2304252.xml

Este esquema garantizará que nunca tendrá más de 100 archivos en cada directorio.

Me he encontrado con este problema muchas veces en el pasado.Intentamos almacenar por fecha, comprimir archivos debajo de la fecha para que no tenga muchos archivos pequeños, etc.Todos ellos fueron parches para el problema real de almacenar los datos como muchos archivos pequeños en NTFS.

Puede ir a ZFS o algún otro sistema de archivos que maneje mejor archivos pequeños, pero aún así detenerse y preguntar si NECESITA almacenar los archivos pequeños.

En nuestro caso, finalmente fuimos a un sistema en el que todos los archivos pequeños para una fecha determinada se agregaban en forma de TAR con delimitadores simples para analizarlos.Los archivos de disco pasaron de 1,2 millones a menos de unos pocos miles.De hecho, se cargaron más rápido porque NTFS no puede manejar muy bien los archivos pequeños y, de todos modos, la unidad pudo almacenar en caché un archivo de 1 MB.En nuestro caso, el tiempo de acceso y análisis para encontrar la parte correcta del archivo fue mínimo en comparación con el almacenamiento y mantenimiento real de los archivos almacenados.

Además de colocar los archivos en subdirectorios...

Personalmente, desarrollaría una aplicación que mantenga igual la interfaz de esa carpeta, es decir, que todos los archivos se muestren como archivos individuales.Luego, en el fondo de la aplicación, toma estos archivos y los combina en archivos más grandes (y dado que los tamaños siempre son 64k, obtener los datos que necesita debería ser relativamente fácil) para deshacerse del desorden que tiene.

Por lo tanto, aún puedes facilitarles el acceso a los archivos que desean, pero también te permite tener más control sobre cómo está estructurado todo.

¿Considera enviarlos a otro servidor que utilice un sistema de archivos más amigable para cantidades masivas de archivos pequeños (Solaris con ZFS, por ejemplo)?

Si hay aspectos significativos y categóricos de los datos, puede anidarlos en un árbol de directorios.Creo que la desaceleración se debe a la cantidad de archivos en un directorio, no a la gran cantidad de archivos en sí.

La agrupación general más obvia es por fecha y le brinda una estructura de anidamiento de tres niveles (año, mes, día) con un límite relativamente seguro para la cantidad de archivos en cada directorio hoja (1-3k).

Incluso si puede mejorar el rendimiento del sistema de archivos/explorador de archivos, parece que este es un problema con el que se encontrará en otros 2 o 3 años...Simplemente mirar una lista de archivos de 0,3 a 1 mil generará un costo, por lo que puede ser mejor a largo plazo encontrar formas de mirar solo subconjuntos más pequeños de archivos.

El uso de herramientas como 'buscar' (en cygwin o mingw) puede hacer que la presencia del árbol de subdirectorios no sea un problema al explorar archivos.

Cambie el nombre de la carpeta cada día con una marca de tiempo.

Si la aplicación guarda los archivos en c: eadings, configure una tarea programada para cambiar el nombre de Lectura a medianoche y cree una nueva carpeta vacía.

Luego obtendrá una carpeta para cada día, cada una con varios miles de archivos.

Puede ampliar el método para agrupar por mes.Por ejemplo, C: eading se convierte en c:\Archive\September\22.

Debe tener cuidado con el tiempo para asegurarse de no intentar cambiar el nombre de la carpeta mientras el producto se guarda en ella.

Para crear una estructura de carpetas que se amplíe a una gran cantidad desconocida de archivos, me gusta el siguiente sistema:

Divida el nombre del archivo en partes de longitud fija y luego cree carpetas anidadas para cada parte excepto la última.

La ventaja de este sistema es que la profundidad de la estructura de carpetas sólo crece tanto como la longitud del nombre del archivo.Entonces, si sus archivos se generan automáticamente en una secuencia numérica, la estructura solo será profunda si es necesario.

12.jpg -> 12.jpg
123.jpg -> 12\123.jpg
123456.jpg -> 12\34\123456.jpg

Este enfoque significa que las carpetas contienen archivos y subcarpetas, pero creo que es una compensación razonable.

Y aquí hay un hermoso ¡PowerShell de una sola línea para ponerte en marcha!

$s = '123456'

-join  (( $s -replace '(..)(?!$)', '$1\' -replace '[^\\]*$','' ), $s )
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top