¿Almacenar muchas imágenes en un solo directorio ralentiza la recuperación de imágenes?

StackOverflow https://stackoverflow.com/questions/1613087

  •  06-07-2019
  •  | 
  •  

Pregunta

Si tengo un sitio en el que los usuarios pueden cargar tantas imágenes como quieran (creo que es similar a photobucket), ¿cuál es la mejor manera de configurar el almacenamiento de archivos (también, todas las cargas tienen una marca de tiempo aleatoria única)?

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 (mantener todas las cargas en el mismo directorio), pero me pregunto si sería más lento al recuperar una imagen si hay miles de imágenes en el mismo directorio

--- editar ---

Gracias por las grandes respuestas hasta ahora. Además, crearé miniaturas, por lo que también tendría que insertar ese directorio en algún lugar ... o , crear una convención de nomenclatura como thumb_whatever.jpg.

tantas maneras diferentes de hacer esto. Sí, el espacio en disco será un problema. pero por ahora me preocupa el tiempo de recuperación. Cuando tengo que enviar una imagen al navegador, si esa imagen se encuentra en un directorio con otras 10,000 imágenes, me preocupa la lentitud con la que eso podría llegar.

¿Fue útil?

Solución

El número de archivos en un directorio no debe tener ningún efecto en el tiempo requerido para leer los datos de un archivo, pero puede afectar masivamente la cantidad de tiempo necesario para encontrar el archivo antes de que pueda comenzar a leerlo.

Los puntos de ruptura exactos en los que se inician los principales problemas variarán de un tipo de sistema de archivos a otro, pero, en general, si se trata de unos pocos cientos de archivos, no tiene que preocuparse mucho por ello. Si está hablando de unos pocos miles, vale la pena reflexionar y quizás hacer un poco de evaluación comparativa para ver cómo su sistema de archivos y hardware lo manejan. Si está hablando de decenas de miles de archivos, entonces realmente necesita comenzar a dividir las cosas. (Una vez tuve un servidor de impresión Linux / e2fs donde CUPS no estaba borrando sus archivos de control de trabajos después de que terminó de imprimir y acumuló alrededor de 100,000 archivos en un directorio. El solo hecho de obtener una lista de directorios tomó más de media hora antes de que empezara a funcionar mostrar cualquier nombre de archivo.)

Sin embargo,

separarlos por nombre de usuario puede no ser la mejor opción, ya que es probable que haya muchos usuarios que carguen muy pocas imágenes y quizás una pareja que cargue cientos o miles de imágenes, lo que podría crear problemas de tiempo de acceso. directorios de almacenamiento de los usuarios. El problema más grande en ese escenario es que es probable que termine (suponiendo 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 su datos.

Ya que vas a tener una marca de tiempo en ellos, lo que probablemente haría es colocarlos en subdirectorios basados ??en los últimos tres dígitos de la marca de tiempo. Eso distribuirá los archivos de manera relativamente uniforme en 1000 subdirectorios y debe mantener el número de archivos en cada directorio razonablemente pequeño. (El uso de los tres primeros dígitos causaría que se llenara un directorio antes de pasar al siguiente en lugar de distribuirlos de manera uniforme). Si aún tiene 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, por lo que subir-1234567890.jpg terminaría en /567/890/upload-1234567890.jpg.

Otros consejos

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

Lo que mejoraría la situación sería una cantidad de subdirectorios debajo de la carpeta de imágenes (o dos niveles, dependiendo de cuántas imágenes esté viendo almacenar), por lo que tiene una jerarquía como esta:

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

... y luego almacene los archivos según su primera letra (de modo que todas las imágenes con nombres que empiecen por "a" van a la carpeta "a"). Podría tener esto como un sufijo de dos o tres letras (aa, ab, ac, anuncio ..., ba, bb, bc ..., zx, zy, zz) y posiblemente tenga una jerarquía debajo de eso también para que se divida 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á que los archivos se distribuyan de manera uniforme 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 las imágenes en una jerarquía como lo he descrito anteriormente. Eso aseguraría que si un solo usuario carga muchos archivos, entonces está cubierto. De manera similar, si está viendo una gran cantidad de directorios de usuarios, se aplica el mismo principio para asegurarse de que no tenga 1,000,000 directorios de usuarios bajo un solo padre.

intente usar mongodb ... es una base de datos de valores clave que también permite almacenar datos binarios. Es muy rápido y eficiente y admite la fragmentación (colocación de datos en varias máquinas) fuera de la caja

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

A menudo uso un esquema como este: sube / (# id% 1000) /img_#id.jpg

Donde #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.

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 los directorios más rápidamente si son más pequeños.

Definitivamente iría con # 2: dividir las imágenes en directorios por usuario.

Creo que los subdirectorios en el directorio de subidas 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. :)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top