2008-09-22 43 views
22

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 300000 archivos en un solo directorio y el número sigue creciendo. Esto ha hecho que el acceso a los directorios padre/ancestro del explorador de Windows requiera mucho tiempo.¿Cómo lidiar con muchos archivos pequeños?

He intentado apagar el servicio de indexación pero eso no hizo ninguna diferencia. También he contemplado mover el contenido del archivo a una base de datos/archivos comprimidos/archivos comprimidos, pero es beneficioso para nosotros acceder a los archivos individualmente; Básicamente, los archivos siguen siendo necesarios para fines de investigación y los investigadores no están dispuestos a tratar con ninguna otra cosa.

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

+2

[rendimiento NTFS y grandes volúmenes de archivos y directorios] (http://stackoverflow.com/q/197162/365102) –

Respuesta

25

El rendimiento NTFS se degrada severamente después de 10.000 archivos en un directorio. Lo que hace es crear un nivel adicional en la jerarquía de directorios, con cada subdirectorio con 10,000 archivos.

Por lo que vale, este es el enfoque que la gente de SVN tomó en version 1.5. Usaron 1,000 archivos como el umbral predeterminado.

+0

Sé que mucha gente recomienda este enfoque, pero he elegido esta respuesta, ya que cita un proyecto de software de buena reputación. Gracias por todas las respuestas. –

+8

¿Tiene un enlace que explique por qué el rendimiento se degrada gravemente después de 10.000 archivos? –

+1

Con NTFS, puede manejar decenas de millones de archivos antes de necesitar crear subcarpetas http://stackoverflow.com/a/291292/141172 –

4

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

Además, ¿podría mover los archivos anteriores a, por ejemplo, un año, a una ubicación diferente (pero accesible)?

Finalmente, y de nuevo, esto requiere que pueda calcular los nombres, encontrará que acceder directamente a un archivo es mucho más rápido que tratar de abrirlo a través del explorador. Por ejemplo, decir
notepad.exe "P: \ ath \ a \ su \ filen.ame"
desde la línea de comandos en realidad debería ser bastante rápido, suponiendo que conoce la ruta del archivo que necesita sin tener que obtener una lista de directorio.

0

Considere empujarlos a otro servidor que use un sistema de archivos más amigable para grandes cantidades de archivos pequeños (Solaris w/ZFS por ejemplo)?

5

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

2

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 profundos de dos niveles. Los archivos se distribuyen uniformemente en los directorios inferiores.

2

Aparte de la colocación de los archivos en los subdirectorios ..

Personalmente, me gustaría desarrollar una aplicación que mantiene la interfaz a esa carpeta la misma, es decir, todos los archivos se muestran como archivos individuales. Luego, en la aplicación, el fondo realmente toma estos archivos y los combina en archivos más grandes (y dado que los tamaños son siempre 64k obteniendo los datos que necesita deben ser relativamente fáciles) Para deshacerse del desastre que tiene.

De modo que aún puede facilitarles el acceso a los archivos que desean, pero también le permite tener más control sobre cómo se estructura todo.

2

Puede intentar usar algo como Solid File System.

Esto le proporciona 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 un archivo se encuentra en su disco duro.

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

1

Si hay algún significativas, categóricas, los aspectos de los datos que pudiera nido 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 más obvia y general es por fecha y le proporciona una estructura de anidación de tres niveles (año, mes, día) con un límite relativamente seguro en el número de archivos en cada directorio de hoja (1-3k).

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

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

8

El problema de rendimiento está causado por la gran cantidad de archivos en un único directorio: una vez que elimines eso, deberías estar bien. Este no es un problema específico de NTFS: de hecho, se lo suele encontrar con los archivos de inicio/correo del usuario 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 tienen nombres de archivo de longitud similar, p. ABCDEFGHI.db, ABCEFGHIJ.db, etc, crear una estructura de directorios como esto:

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

Utilizando esta estructura, se puede localizar rápidamente un archivo basándose en su nombre. Si los nombres de archivo tienen longitudes variables, elija una longitud máxima y anteceda ceros (o cualquier otro carácter) para determinar el directorio al que pertenece el archivo.

+1

Es mejor utilizar la división inversa en los nombres de los directorios: mejorará el tiempo de búsqueda dentro del último directorio eliminando el prefijo de nombres similares, por ejemplo: GHI \ DEF \ ABCDEFGHI.db – ursa

1

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

Si la aplicación está guardando los archivos en c: \ Readings, configure una tarea programada para renombrar Reading at midnight y cree una nueva carpeta vacía.

A continuación, obtendrá una carpeta por cada día, cada uno con varios miles de archivos.

Puede ampliar el método más a grupos por mes. Por ejemplo, C: \ Reading se convierte en c: \ Archive \ September \ 22.

Debe tener cuidado con el tiempo para asegurarse de que no está intentando cambiar el nombre de la carpeta mientras el producto se está guardando.

3

Tener cientos de miles de archivos en un único directorio invalidará NTFS, y no hay mucho que pueda hacer al respecto. Debería reconsiderar el almacenamiento de los datos en un formato más práctico, como un gran tarball 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 poner los archivos en diferentes dependiendo del nombre del archivo. De esta forma, aún puede almacenar y cargar sus archivos sabiendo solo el nombre del archivo.

El método que usamos es tomar las últimas letras del nombre del archivo, invertirlas y crear directorios de una letra a partir de eso. Tenga en cuenta los siguientes archivos, por ejemplo:

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

puede clasificarlos 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 se asegurará de que usted nunca tendrá más de 100 archivos en cada directorio.

2

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

Puede ir a ZFS o a algún otro sistema de archivos que maneje mejor los archivos pequeños, pero aún 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 anexaban en forma de TAR con delimitadores simples para analizarlos. Los archivos del disco pasaron de 1,2 millones a menos de unos miles. De hecho, se cargaron más rápido porque NTFS no puede manejar los archivos pequeños muy bien, y la unidad fue capaz de almacenar en caché un archivo de 1MB de todos modos. 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 el mantenimiento real de los archivos almacenados.

27

NTFS en realidad funcionará bien con más de 10.000 archivos en un directorio, siempre y cuando le diga que deje de crear nombres de archivos alternativos compatibles con las plataformas de Windows de 16 bits. De forma predeterminada, NTFS crea automáticamente un nombre de archivo '8 dot 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é en uso. Puede deshabilitar la designación '8 dot 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 dot 3' solo son necesarios para los programas escritos para versiones muy antiguas de Windows.

Se requiere reiniciar antes de que esta configuración surta efecto.

+3

Se recomienda desactivar 8 puntos 3 por encima de 300,000 archivos. http://technet.microsoft.com/en-us/library/cc778996(WS.10).aspx Puede cambiar el comportamiento desde la línea de comando en las versiones más nuevas de Windows, p. ej. 'fsutil 8dot3name set 1'. –

0

Para crear una estructura de carpetas que va a escalar a un gran número indeterminado de archivos, me gusta el siguiente sistema:

Dividir el nombre del archivo en trozos de longitud fija, y luego crear carpetas anidadas para cada pieza, excepto la última.

La ventaja de este sistema es que la profundidad de la estructura de la carpeta solo crece con la profundidad del nombre del archivo. Entonces, si sus archivos se generan automáticamente en una secuencia numérica, la estructura solo es profunda, debe ser.

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 que pueda seguir!

$s = '123456' 

-join (($s -replace '(..)(?!$)', '$1\' -replace '[^\\]*$',''), $s) 
Cuestiones relacionadas