2009-10-23 9 views
13

Si tengo un sitio donde los usuarios pueden cargar tantas imágenes como deseen (piense en una foto similar), ¿cuál es la mejor manera de configurar el almacenamiento de archivos (también, todas las subidas obtienen una marca de tiempo aleatoria única)?¿El almacenamiento de muchas imágenes en un único directorio ralentiza la recuperación de imágenes?

site root 
--username 
----image1.jpg 
----image2.jpg 
----image3.jpg 
--anotheruser 
----image1.jpg 
----image2.jpg 
----image3.jpg 
... 

o

siteroot 
--uploads 
----image1.jpg 
----image2.jpg 
----image3.jpg 
----image4.jpg 
----image6.jpg 
... 
----image50000.jpg 

creo que el primer método es más organizado. Pero creo que el segundo método es estándar (manteniendo todas las cargas en el mismo directorio), pero me pregunto si sería más lento recuperar una imagen si hay miles de imágenes en el mismo directorio

--- editar - -

Gracias por las excelentes respuestas hasta el momento. Además, crearé miniaturas, por lo que también tendría que insertar ese directorio en alguna parte ... o, crear una convención de nomenclatura como thumb_whatever.jpg.

tantas formas diferentes de hacerlo. Sí, el espacio en disco será un problema. pero por ahora estoy preocupado con el tiempo de recuperación. Cuando tengo que mostrar una imagen en el navegador, si esa imagen está en un directorio con otras 10.000 imágenes, me preocupa lo lento que podría ser.

Respuesta

19

El número de archivos en un directorio no debería tener ningún efecto en el tiempo requerido para leer los datos de un archivo, pero puede afectar enormemente la cantidad de tiempo necesaria para encontrar el archivo antes de poder comenzar a leerlo.

Los puntos de corte exactos donde se inician los principales problemas variarán desde el tipo de sistema de archivos al tipo de sistema de archivos, pero, en general, si habla de unos pocos cientos de archivos, no necesita preocuparse por ello. Si está hablando de unos miles, vale la pena pensar y quizás hacer una pequeña evaluación comparativa para ver cómo lo maneja su sistema de archivos y hardware. Si estás hablando de decenas de miles de archivos, entonces realmente necesitas comenzar a romper las cosas. (Una vez tuve un servidor de impresión Linux/e2fs donde CUPS no borraba sus archivos de control de trabajos una vez que terminaba de imprimir y tenía unos 100.000 archivos en un directorio. Solo obtener una lista de directorios requería más de media hora antes de que comenzara a mostrar los nombres de archivo.)

Sin embargo, separarlos por nombre de usuario puede no ser la mejor opción, ya que es probable que haya muchos usuarios subiendo muy pocas imágenes y quizás una pareja que cargue cientos o miles de imágenes, potencialmente creando problemas de tiempo de acceso en los directorios de almacenamiento de esos usuarios. El problema más grande en ese escenario es que probablemente terminarías (asumiendo un sitio exitoso) con miles o decenas de miles de usuarios y una gran cantidad de subdirectorios es tan malo como una gran cantidad de archivos para ralentizar el acceso a tu sitio. datos.

Puesto que usted va a tener una marca de tiempo en ellos, lo que haría probablemente se los puso en subdirectorios a partir de los últimos de tres dígitos de la marca de tiempo. Eso distribuirá los archivos de manera relativamente uniforme en 1000 subdirectorios y debería mantener el número de archivos en cada directorio razonablemente pequeño. (El uso de los tres primeros dígitos provocaría que se completara un directorio antes de pasar al siguiente en lugar de distribuirlos de manera uniforme.) Si todavía está terminando con demasiados archivos en cada subdirectorio (lo que probablemente significaría que está tratando con varios millones de imágenes cargadas), podría agregar un segundo nivel para los tres dígitos anteriores, de modo que upload-1234567890.jpg terminaría en /567/890/upload-1234567890.jpg.

+2

técnica muy interesante – Yarin

0

Creo que los subdirectorios en el directorio de cargas serían los mejores.

site root 
--uploads 
----username 
------image1.jpg 
------image2.jpg 
------image3.jpg 
----anotheruser 
------image1.jpg 
------image2.jpg 
------image3.jpg 
... 

Dependiendo del sistema operativo host, tener demasiados archivos en un directorio podría causar algunos dolores de cabeza y problemas de compatibilidad. Además, dependiendo de cómo obtenga la lista de imágenes, podría causar problemas de rendimiento.

Además, la opción 2 sería un desastre. :)

5

La respuesta a eso es "tal vez". Es posible que la recuperación de archivos esté bien, pero si necesita realizar algún mantenimiento en la carpeta, sería un gran dolor de cabeza ya que los procesos intentan enumerar las listas de directorios.

lo que podría mejorar la situación sería un número de subdirectorios en la carpeta de imágenes (o dos niveles, dependiendo del número de imágenes que se encuentra en el mercado de almacenamiento), por lo que tiene una jerarquía de esta manera:

siteroot 
-- uploads 
---- a 
---- b 
---- c 
    : 
---- z 

... y luego almacenar archivos en función de su primera letra (por lo que todas las imágenes con nombres que comienzan en 'a' van a la carpeta 'a'). Podrías tener esto como un sufijo de dos o tres letras (aa, ab, ac, ad ..., ba, bb, bc ..., zx, zy, zz) y posiblemente tener una jerarquía debajo de eso también para que te dividas archivos en varias carpetas que dependen de los primeros cuatro caracteres del nombre.

Si a los archivos se les asigna un nombre alfanumérico aleatorio, esto garantizaría que los archivos se distribuyan uniformemente en todas las carpetas (dado un tamaño de muestra lo suficientemente grande).

Es posible que desee considerar una combinación de su opción (1) y dividir imágenes en una jerarquía como he descrito anteriormente. Eso garantizaría que si un usuario único sube muchos archivos, entonces esté cubierto. De manera similar, si está mirando muchos directorios de usuarios, se aplica el mismo principio para asegurarse de que no tenga 1,000,000 de directorios de usuarios en un solo padre.

+0

todo bien ... hasta que se quede sin espacio de disco. – Toad

+3

@reinier: tendrás problemas de espacio de disco sin importar la estrategia que uses. Al final del día, depende del software manejar una falla correctamente. Si está pensando en contar inodo, entonces dos jerarquías de carpetas son 676 nodos (suponiendo únicamente A-Z). El OP está preocupado con decenas de miles de archivos.Agregar algunos directorios no va a afectar eso. –

+0

chris: bueno, no si usas una base de datos donde agregar espacio extra es tan fácil como configurar un archivo ini. Con los esquemas de carpetas como usted sugiere, agregar discos duros físicos adicionales llevaría a cambiar el esquema de nombres y así tener que escribir una secuencia de comandos que mueva todos los archivos y carpetas al nuevo esquema, potencialmente en ejecución por días – Toad

2

intente utilizar mongodb ...es un db keyvalue que también permite almacenar datos binarios. Es muy rápido y eficiente y admite fragmentación (colocando datos en varias máquinas)

realmente no desea tener carpetas y carpetas llenas de archivos. Administrar estas carpetas lleva una eternidad, y cambiar el esquema de nomenclatura/división más tarde es una pesadilla. Además, si te quedas sin espacio de disco, tienes un problema. También para el equilibrio de carga, tener un disco duro lleno de archivos no es eficiente

1

Depende del sistema de archivos. Por ejemplo, FAT16 tiende a ser bastante lento si tiene más de 512 archivos en un directorio. FAT32 y NTFS no tienen las mismas limitaciones pero también se ejecutan mucho más lentamente si tiene una cantidad extremadamente grande de archivos. Incluso si está ejecutando uno de los sistemas de archivos Linux más robustos, aún podrá analizar directorios más rápidamente si son más pequeños.

Definitivamente iré con # 2 - dividiendo las imágenes en directorios por usuario.

2

A menudo utilizan el esquema de esta manera: subidas/(# id% 1000) /img_#id.jpg

Dónde #id es OFC. número de identificación (entero) de la foto almacenada en la base de datos. Eso proporciona un esquema simple basado solo en la identificación de la foto.

Cuestiones relacionadas