Almacenar un millón de imágenes en el sistema de archivos


79

Tengo un proyecto que generará una gran cantidad de imágenes. Alrededor de 1,000,000 para comenzar. No son imágenes grandes, así que las guardaré todas en una máquina al inicio.

¿Cómo recomienda almacenar estas imágenes de manera eficiente? (Sistema de archivos NTFS actualmente)

Estoy considerando un esquema de nomenclatura ... para comenzar, todas las imágenes tendrán un nombre incremental de 1 en adelante. Espero que esto me ayude a ordenarlas más tarde si es necesario, y arrojarlas en diferentes carpetas.

¿Cuál sería un mejor esquema de nombres?

a / b / c / 0 ... z / z / z / 999

o

a / b / c / 000 ... z / z / z / 999

alguna idea sobre esto?


1
¿Están vinculados a usuarios específicos o simplemente genéricos? ¿Están agrupados de alguna manera?

solo genérico Un montón de imágenes generadas por algunos equipos técnicos. Los nombro incrementales de 1 en adelante solo para tener una idea de una referencia temporal.
s.mihai

¿Cómo se van a utilizar / acceder? a través de una aplicación a medida o qué?
paloma

16
¿Este Eres tu? i46.tinypic.com/1z55k7q.jpg

1
:)) sí ... 1 mil. imágenes porno :))
s.mihai

Respuestas:


73

Recomiendo usar un sistema de archivos normal en lugar de bases de datos. Usar el sistema de archivos es más fácil que una base de datos, puede usar herramientas normales para acceder a los archivos, los sistemas de archivos están diseñados para este tipo de uso, etc. NTFS debería funcionar bien como sistema de almacenamiento.

No almacene la ruta real a la base de datos. Es mejor almacenar el número de secuencia de la imagen en la base de datos y tener una función que pueda generar la ruta desde el número de secuencia. p.ej:

 File path = generatePathFromSequenceNumber(sequenceNumber);

Es más fácil de manejar si necesita cambiar la estructura del directorio de alguna manera. Tal vez necesite mover las imágenes a una ubicación diferente, tal vez se quede sin espacio y comience a almacenar algunas de las imágenes en el disco A y algunas en el disco B, etc. Es más fácil cambiar una función que cambiar las rutas en la base de datos .

Usaría este tipo de algoritmo para generar la estructura de directorios:

  1. Primero rellene el número de secuencia con ceros a la izquierda hasta que tenga al menos una cadena de 12 dígitos. Este es el nombre de su archivo. Es posible que desee agregar un sufijo:
    • 12345 -> 000000012345.jpg
  2. Luego divida la cadena en bloques de 2 o 3 caracteres donde cada bloque denota un nivel de directorio. Tener un número fijo de niveles de directorio (por ejemplo 3):
    • 000000012345 -> 000/000/012
  3. Almacene el archivo en el directorio generado:
    • Por lo tanto, la ruta completa y el nombre del archivo para el archivo con ID de secuencia 123es 000/000/012/00000000012345.jpg
    • Para el archivo con id de secuencia, 12345678901234la ruta sería123/456/789/12345678901234.jpg

Algunas cosas a considerar sobre las estructuras de directorios y el almacenamiento de archivos:

  • El algoritmo anterior le ofrece un sistema en el que cada directorio hoja tiene un máximo de 1000 archivos (si tiene menos de un total de 1 000 000 000 000 de archivos)
  • Puede haber límites sobre cuántos archivos y subdirectorios puede contener un directorio, por ejemplo , el sistema de archivos ext3 en Linux tiene un límite de 31998 subdirectorios por directorio.
  • Las herramientas normales (WinZip, Windows Explorer, línea de comandos, bash shell, etc.) pueden no funcionar muy bien si tiene una gran cantidad de archivos por directorio (> 1000)
  • La estructura del directorio en sí ocupará algo de espacio en el disco, por lo que no querrá demasiados directorios.
  • Con la estructura anterior, siempre puede encontrar la ruta correcta para el archivo de imagen simplemente mirando el nombre del archivo, si resulta que estropea las estructuras de su directorio.
  • Si necesita acceder a archivos desde varias máquinas, considere compartir los archivos a través de un sistema de archivos de red.
  • La estructura de directorios anterior no funcionará si elimina muchos archivos. Deja "agujeros" en la estructura del directorio. Pero como no está eliminando ningún archivo, debería estar bien.

1
¡muy interesante! dividiendo el nombre de archivo ... no pensé en eso. Supongo que esta es la forma elegante de hacerlo: -?
s.mihai

37
Usar un hash (como MD5) como nombre del archivo, así como la distribución del directorio, funcionaría. La integridad de los archivos no solo sería un beneficio secundario para el esquema de nombres (se verifica fácilmente), sino que tendrá una distribución razonablemente uniforme en toda la jerarquía de directorios. Entonces, si tiene un archivo llamado "f6a5b1236dbba1647257cc4646308326.jpg", lo almacenará en "/ f / 6" (o tan profundo como lo necesite). 2 niveles de profundidad da 256 directorios, o poco menos de 4000 archivos por directorio para los archivos iniciales de 1 m. También sería muy fácil automatizar la redistribución a un esquema más profundo.

+1 Acabo de notar que esta respuesta es similar a la que acabo de publicar.
3dinfluence

1
Definitivamente estoy de acuerdo en usar el sistema de archivos y crear un identificador oficial para "cortar" los nombres de las carpetas. Pero también debe intentar obtener una distribución aleatoria de identificadores, es decir, no utilice un número de secuencia. Eso le permitiría tener un árbol de carpetas más equilibrado. Además, con la distribución aleatoria puede particionar más fácilmente el árbol en múltiples sistemas de archivos. También usaría una SAN basada en ZFS con deduplicación activada y un volumen escaso para cada sistema de archivos. Todavía podría usar NTFS utilizando iSCSI para acceder a la SAN.
Michael Dillon el

Si va de derecha a izquierda en el paso 2, los archivos se distribuyen de manera uniforme. Además, no tiene que preocuparse de no estar llenando suficientes ceros, ya que puede un número ilimitado de archivos
ropo

31

Voy a poner mis 2 centavos en un consejo negativo: no vaya con una base de datos.

He estado trabajando con bases de datos de almacenamiento de imágenes durante años: archivos grandes (1 meg-> 1 concierto), a menudo modificados, múltiples versiones del archivo, a las que se accede con bastante frecuencia. Los problemas de la base de datos con los que se encuentran almacenados los archivos grandes son extremadamente tediosos, los problemas de escritura y transacción son complicados y se topan con problemas de bloqueo que pueden causar grandes accidentes de tren. Tengo más práctica dbcc en escribir guiones, y la restauración de las tablas de copias de seguridad que cualquier persona normal debe siempre tener.

La mayoría de los sistemas más nuevos con los que he trabajado han trasladado el almacenamiento de archivos al sistema de archivos, y dependían de las bases de datos para nada más que la indexación. Los sistemas de archivos están diseñados para soportar ese tipo de abuso, son mucho más fáciles de expandir y rara vez se pierde todo el sistema de archivos si una entrada se corrompe.


si. nota tomada!
s.mihai

55
¿Has mirado el tipo de datos FILESTREAM de SQL 2008? Es un cruce entre la base de datos y el almacenamiento del sistema de archivos.
NotMe

+1 en seguir con el servidor de archivos en lugar de una base de datos, ya que está haciendo operaciones de E / S rápidas e infrecuentes.

¿Qué sucede si solo está almacenando unos cientos de documentos o fotos por base de datos, alguna desventaja de usar la base de datos para el almacenamiento?
Beep beep

1
+1 ... un sistema de archivos es una especie de "base de datos" de todos modos (ntfs seguro), entonces, ¿por qué hacerlo demasiado complicado?
akira

12

Creo que la mayoría de los sitios que tienen que lidiar con esto usan algún tipo de hash para asegurarse de que los archivos se distribuyan uniformemente en las carpetas.

Digamos que tiene un hash de un archivo que es algo como esto 515d7eab9c29349e0cde90381ee8f810
. Podría tener esto almacenado en la siguiente ubicación y puede usar cuántos niveles de profundidad necesita para mantener baja la cantidad de archivos en cada carpeta.
\51\5d\7e\ab\9c\29\349e0cde90381ee8f810.jpg

He visto este enfoque tomado muchas veces. Todavía necesita una base de datos para asignar estos hashes de archivos a un nombre legible por humanos y cualquier otro metadato que necesite almacenar. Pero este enfoque escala bastante bien porque puede comenzar a distribuir el espacio de direcciones hash entre múltiples computadoras y / o grupos de almacenamiento, etc.


2
Git utiliza un enfoque similar: git-scm.com/book/en/v2/Git-Internals-Git-Objects (para respaldar esta respuesta)
aexl

11

Idealmente, debe ejecutar algunas pruebas en tiempos de acceso aleatorio para varias estructuras, ya que la configuración específica del disco duro, el almacenamiento en caché, la memoria disponible, etc. pueden cambiar estos resultados.

Suponiendo que tenga control sobre los nombres de archivo, los dividiría al nivel de 1000 por directorio. Cuantos más niveles de directorio agregue, más inodos quemará, por lo que aquí hay un push-pull.

P.ej,

/ root / [0-99] / [0-99] / filename

Tenga en cuenta que http://technet.microsoft.com/en-us/library/cc781134(WS.10).aspx tiene más detalles sobre la configuración de NTFS. En particular, "si usa grandes cantidades de archivos en una carpeta NTFS (300,000 o más), desactive la generación de nombres de archivos cortos para un mejor rendimiento, y especialmente si los primeros seis caracteres de los nombres largos son similares".

También debe buscar deshabilitar las funciones del sistema de archivos que no necesita (por ejemplo, último tiempo de acceso). http://www.pctools.com/guides/registry/detail/50/


3
+1 para deshabilitar la generación de nombre de archivo 8.3 y el último tiempo de acceso; eso fue lo primero que me vino a la mente cuando leí "gran cantidad de [archivos]" y "NTFS" (Windows).
robar

link down ........................
Pacerier

7

Hagas lo que hagas, no los guardes en un solo directorio.

Dependiendo de la distribución de los nombres de estas imágenes, puede crear una estructura de directorio donde tenga carpetas de nivel superior de una sola letra donde tendría otro conjunto de subcarpetas para la segunda letra de imágenes, etc.

Entonces:

La carpeta img\a\b\c\d\e\f\g\contendría las imágenes que comienzan con 'abcdefg' y así sucesivamente.

Puede introducir su propia profundidad apropiada requerida.

Lo mejor de esta solución es que la estructura de directorios actúa efectivamente como una tabla hash / diccionario. Dado un nombre de archivo de imagen, conocerá su directorio y, dado un directorio, conocerá un subconjunto de imágenes que van allí.


\ a \ b \ c \ d \ e \ f \ lo estoy haciendo ahora, estaba pensando que hay una forma inteligente de hacerlo.
s.mihai

1
Esa es una solución generalmente aceptada de cómo almacenarlos físicamente. Claramente, generar la URL de la imagen es algo que se puede hacer fácilmente de forma dinámica en función del nombre del archivo de imagen. Además, para servirlos, incluso podría introducir los subdominios img-a, img-b en el servidor de imágenes si lo desea, para acelerar los tiempos de carga.

2
Y +1 para "no los guarde todos en un directorio". Estoy admitiendo un sistema heredado que ha colocado más de 47000 archivos en un servidor en una sola carpeta, y Explorer tarda aproximadamente un minuto en abrir la carpeta.
Mark Ransom

55
Hacer a \ b \ c \ d \ e \ f \ g hace que la estructura del directorio sea muy profunda y cada directorio contiene solo unos pocos archivos. Es mejor usar más de una letra por nivel de directorio, por ejemplo, ab \ cd \ ef \ o abc \ def \. Los directorios también ocupan espacio del disco, por lo que no querrá demasiados.
Juha Syrjälä

2
Tuve que admitir una aplicación que tenía más de 4 millones de archivos en un solo directorio; funcionó sorprendentemente bien, pero NUNCA podría conseguir que el explorador abriera la carpeta, continuamente ordenaría las nuevas adiciones. +1 para que NTFS pueda manejarlo sin morir.
SqlACID

5

Los almacenaría en el sistema de archivos, pero depende de qué tan rápido crezca el número de archivos. ¿Estos archivos están alojados en la web? ¿Cuántos usuarios accederían a este archivo? Estas son las preguntas que deben responderse antes de que pueda darle una mejor recomendación. También miraría a Haystack de Facebook, tienen una muy buena solución para almacenar y servir imágenes.

Además, si elige el sistema de archivos, necesitará particionar estos archivos con directorios. Estuve analizando este problema y propuse una solución, pero no es perfecta de ninguna manera. Estoy particionando por tabla hash y los usuarios pueden leer más en mi blog .


Las imágenes no son para acceso frecuente. entonces no hay problema con esto. su número crecerá bastante rápido. Supongo que habrá 1mil. marca en 1 mes.
s.mihai

Estoy interesado en la vista del programador para que no
piense

Entonces, si no necesita acceso rápido, probablemente Haystack no sea para usted. Usar directorios para particiones es la solución más simple en mi opinión.
Lukasz

5

Tenemos un sistema de tienda de fotos con 4 millones de imágenes. Usamos la base de datos solo para metadatos y todas las imágenes se almacenan en el sistema de archivos usando un sistema de nombres inversos, donde los nombres de las carpetas se generan a partir del último dígito del archivo, last-1, etc. por ejemplo: 000001234.jpg se almacena en la estructura de directorios como 4 \ 3 \ 2 \ 1 \ 000001234.jpg.

Este esquema funciona muy bien con el índice de identidad en la base de datos, ya que llena de manera uniforme toda la estructura de directorios.


4

Punto rápido, no necesita almacenar una ruta de archivo en su base de datos. Simplemente puede almacenar un valor numérico, si sus archivos se nombran de la manera que usted describe. Luego, utilizando uno de los esquemas de almacenamiento bien definidos ya discutidos, puede obtener el índice como un número y encontrar rápidamente el archivo atravesando la estructura del directorio.


: -? Buen punto rápido. solo que ahora no tengo un algoritmo para generar la ruta.
s.mihai


4

¿Deberán nombrarse sus imágenes de forma única? ¿Puede el proceso que genera estas imágenes producir el mismo nombre de archivo más de una vez? Es difícil de decir sin saber qué dispositivo está creando el nombre de archivo, pero diga que el dispositivo se 'reinicia' y al reiniciar comienza a nombrar las imágenes como lo hizo la última vez que se 'reinició', si eso es una preocupación.

Además, dices que alcanzarás 1 millón de imágenes en un mes. ¿Qué tal después de eso? ¿Qué tan rápido continuarán estas imágenes llenando el sistema de archivos? ¿Se completarán en algún momento y se nivelarán en aproximadamente 1 millón de imágenes TOTALES o continuará creciendo y creciendo, mes tras mes?

Le pregunto porque podría comenzar a diseñar su sistema de archivos por mes, luego por imagen. Podría inclinarme a sugerir que almacene las imágenes en dicha estructura de directorio:

imgs\yyyy\mm\filename.ext

where: yyyy = 4 digit year
         mm = 2 digit month

example:  D:\imgs\2009\12\aaa0001.jpg
          D:\imgs\2009\12\aaa0002.jpg
          D:\imgs\2009\12\aaa0003.jpg
          D:\imgs\2009\12\aaa0004.jpg
                   |
          D:\imgs\2009\12\zzz9982.jpg
          D:\imgs\2010\01\aaa0001.jpg (this is why I ask about uniqueness)
          D:\imgs\2010\01\aab0001.jpg

Mes, año, incluso día es bueno para imágenes de tipo de seguridad. No estoy seguro de si esto es lo que está haciendo, pero lo hice con una cámara de seguridad doméstica que tomaba una foto cada 10 segundos ... De esta manera, su aplicación puede profundizar en un tiempo específico o incluso en un rango donde podría pensar que se generó la imagen . O, en lugar de año, mes, ¿hay algún otro "significado" que pueda derivarse del archivo de imagen en sí? ¿Algunos otros descriptores, además del ejemplo de fecha que di?

No almacenaría los datos binarios en la base de datos. Nunca tuve un buen rendimiento / suerte con ese tipo de cosas. No puedo imaginar que funcione bien con 1 millón de imágenes. Almacenaría el nombre del archivo y eso es todo. Si todos van a ser JPG, entonces ni siquiera almacene la extensión. Crearía una tabla de control que almacenara un puntero al servidor del archivo, la unidad, la ruta, etc. De esta manera, puede mover esas imágenes a otro cuadro y aún así ubicarlas. ¿Necesita etiquetar con palabras clave sus imágenes? Si es así, querrá crear las tablas apropiadas que permitan ese tipo de etiquetado.

Usted / otros pueden haber abordado estas ideas mientras respondía ... Espero que esto ayude ...


1.todos los archivos se nombrarán de forma única 2.el sistema crecerá y crecerá al principio, obtendrá alrededor de 1mil imágenes y luego crecerá a un ritmo de un par de decenas de miles por mes. 3. habrá algún tipo de etiquetado de los archivos en algún momento en el futuro, es por eso que quiero almacenar algún tipo de datos de identificación en la base de datos.
s.mihai

3

Estoy involucrado en un proyecto que almacena 8.4 millones de imágenes en el transcurso de un año para documentar el estado de varios dispositivos. Se accede con mayor frecuencia a las imágenes más recientes, y rara vez se buscan imágenes más antiguas a menos que se descubra una condición que motivó a alguien a profundizar en los archivos.

Mi solución, basada en este uso, fue comprimir gradualmente las imágenes en archivos comprimidos. Las imágenes son JPG, cada una de aproximadamente 20kB y no se comprimen mucho, por lo que el esquema de compresión ZIP no es ninguno. Esto se hace simplemente para concatenarlos en una entrada de sistema de archivos que ayuda enormemente a NTFS en términos de velocidad cuando se trata de moverlos de una unidad a otra, o mirar a través de la lista de archivos.

Las imágenes de más de un día se combinan en un zip "diario"; las cremalleras de más de un mes se combinan en su respectiva cremallera "mensual"; y finalmente ya no se necesita nada más de un año y, en consecuencia, se elimina.

Este sistema funciona bien porque los usuarios pueden explorar los archivos (ya sea a través del sistema operativo o de una serie de aplicaciones cliente) y todo se nombra en función de los nombres de los dispositivos y las marcas de tiempo. En general, un usuario conoce estas dos piezas de información y puede localizar rápidamente cualquiera de los millones de imágenes.

Entiendo que esto probablemente no esté relacionado con sus detalles particulares, pero pensé en compartirlo.


2

Tal vez un esquema de nomenclatura basado en la fecha de creación, ya sea que incluya toda la información en el nombre del archivo o (mejor para navegar más tarde) dividiéndolo en directorios. Puedo pensar en lo siguiente, dependiendo de la frecuencia con la que generes imágenes:

  • Varias imágenes generadas cada día: Year/Month/Day/Hour_Minute_Second.png
  • Un par al mes: Year/Month/Day_Hour_Minute_Second.png

etc. Entiendes mi punto ... =)


no se generan de forma continua en el tiempo, por lo que algunas carpetas se convertirán en grasa y otros se quedan ... delgada :))
s.mihai

Bueno, obviamente no tienes que crear cada carpeta, solo porque estás siguiendo este esquema. Incluso podría haberlo hecho Year/Month/Day/Hour/Minute: decida cuántos niveles de carpetas necesita según la frecuencia con la que se generan las imágenes cuando la velocidad es más alta , y luego no cree carpetas que se dejarían vacías.
Tomas Aschan

2

Me inclinaría a crear una estructura de carpetas basada en la fecha, por ejemplo, \ año \ mes \ día, y usar marcas de tiempo para los nombres de archivo. Si es necesario, las marcas de tiempo pueden tener un componente de contador adicional si las imágenes se van a crear tan rápido que puede haber más de una en un milisegundo. Al utilizar una secuencia más significativa a menos significativa para la clasificación de nombres, la búsqueda y el mantenimiento son muy sencillos. por ejemplo, hhmmssmm [seq] .jpg


2

¿Está considerando la recuperación ante desastres?

Algunas de las soluciones propuestas aquí terminan alterando el nombre del archivo (de modo que si el archivo físico se moviera, perdería la pista de qué archivo es realmente). Recomiendo mantener un nombre de archivo físico único para que si su lista maestra de ubicaciones de archivos se corrompe, pueda regenerarla con un pequeño shell, er, powershell, script;)

Por lo que leí aquí, parece que todos estos archivos se almacenarían en un sistema de archivos. Considere almacenarlos en múltiples sistemas de archivos en múltiples máquinas. Si tiene los recursos, determine un sistema de almacenamiento de cada archivo en dos máquinas diferentes en caso de que pierda una fuente de alimentación y el reemplazo esté dentro de 2 días.

Considere qué tipo de procedimientos necesitaría crear para migrar archivos entre máquinas o sistemas de archivos. La capacidad de hacer esto con su sistema en vivo y en línea puede ahorrarle un dolor de cabeza considerable en el futuro.

Puede considerar usar un GUID como nombre de archivo físico en lugar de un número incremental en caso de que su contador de número incremental (¿la columna de identidad de la base de datos?) Se estropee.

Si corresponde, considere usar un CDN como Amazon S3.


2

Si bien no he publicado imágenes en esa escala, anteriormente he escrito una pequeña aplicación de galería para servir ~ 25k imágenes en una máquina w de 400MHz. 512 MB de RAM más o menos. Algunas experiencias;

  • Evite las bases de datos relacionales a toda costa; Si bien las bases de datos, sin duda, son inteligentes en el manejo de datos, no están diseñadas para tal uso (obtuvimos bases de datos de valores clave jerárquicos especializados para los llamados sistemas de archivos ). Si bien no tengo más que una corazonada, apostaría a que el caché de DB se salga por la ventana, si le arrojas gotas realmente grandes. Si bien mi hardware disponible estaba en el extremo pequeño, no tocar la base de datos en absoluto en la búsqueda de imágenes dio órdenes de magnitud mejor velocidad.

  • Investigue cómo se comporta el sistema de archivos; en ext3 (o era ext2 en ese momento, no recuerdo), el límite de poder buscar eficientemente subdirectorios y archivos estaba alrededor de la marca de 256; así que solo tengo esa cantidad de archivos y carpetas en cualquier carpeta. De nuevo, notable aceleración. Si bien no sé sobre NTFS, cosas como XFS (que usa B-trees, por lo que recuerdo) es extremadamente rápido, simplemente porque pueden hacer búsquedas extremadamente rápidas.

  • Distribuir datos de manera uniforme; cuando experimenté con lo anterior, traté de distribuir los datos de manera uniforme en todos los directorios (hice un MD5 de la URL y lo usé para los directorios; /1a/2b/1a2b...f.jpg). De esta forma, lleva más tiempo alcanzar el límite de rendimiento que exista (y la memoria caché del sistema de archivos se anula en conjuntos de datos tan grandes de todos modos). (por el contrario, es posible que desee ver dónde están los límites desde el principio; luego, desea arrojar todo en el primer directorio disponible.


2

Podría llegar tarde al juego en esto. Pero una solución (si se ajusta a su caso de uso) podría ser el hash de nombre de archivo. Es una forma de crear una ruta de archivo fácilmente reproducible utilizando el nombre del archivo y al mismo tiempo crear una estructura de directorio bien distribuida. Por ejemplo, puede usar los bytes del código hash del nombre de archivo como su ruta:

String fileName = "cat.gif";
int hash = fileName.hashCode();
int mask = 255;
int firstDir = hash & mask;
int secondDir = (hash >> 8) & mask;

Esto daría como resultado que la ruta sea:

/172/029/cat.gif

Luego puede encontrar cat.gifen la estructura del directorio reproduciendo el algoritmo.

Usar HEX como nombres de directorio sería tan fácil como convertir los intvalores:

String path = new StringBuilder(File.separator)
        .append(String.format("%02x", firstDir))
        .append(File.separator)
        .append(String.format("%02x", secondDir)
        .toString();

Resultando en:

/AC/1D/cat.gif

Escribí un artículo sobre esto hace unos años y recientemente lo mudé a Medium. Tiene algunos detalles más y un código de muestra: Hashing de nombre de archivo: creación de una estructura de directorio hash . ¡Espero que esto ayude!


Almacenamos 1.8 billones de artículos usando algo similar. Funciona bien. Use un hash que sea rápido y tenga bajas tasas de colisión y ya está listo.
CVVS


1

Si TODOS no son necesarios de inmediato y puede generarlos sobre la marcha y estas son imágenes pequeñas, ¿por qué no implementar una memoria LRU o caché de disco sobre su generador de imágenes?

Esto podría salvarlo del almacenamiento y mantener las imágenes calientes que se servirán desde mem?


1

Acabo de ejecutar una prueba en zfs porque me encanta zfs, y tenía una partición de 500 gig en la que tenía compresión. Escribí un script que generó 50-100k archivos y los coloqué en directorios anidados 1/2/3/4/5/6/7/8 (5-8 niveles de profundidad) y lo dejé correr durante 1 semana. (no fue un gran script). Llenó el disco y terminó teniendo aproximadamente 25 millones de archivos más o menos. El acceso a cualquier archivo con una ruta conocida fue instantáneo. Listado de cualquier directorio con una ruta conocida fue instantánea.

Sin embargo, obtener un recuento de la lista de archivos (a través de buscar) tomó 68 horas.

También ejecuté una prueba poniendo muchos archivos en un directorio. Obtuve alrededor de 3.7 millones de archivos en un directorio antes de detenerme. Listado del directorio para obtener un recuento tomó alrededor de 5 minutos. Eliminar todos los archivos en ese directorio tomó 20 horas. Pero la búsqueda y el acceso a cualquier archivo fue instantáneo.


1

Veo que otros mencionan una base de datos, pero no veo ninguna mención de eso en su publicación. En cualquier caso, mi opinión sobre este punto en particular es: adherirse a una base de datos o sistema de archivos. Si tiene que mezclar los dos, tenga cuidado al respecto. Las cosas se ponen más complicadas. Pero es posible que tengas que hacerlo. Almacenar un millón de fotos en una base de datos no parece la mejor idea.

Es posible que le interese la siguiente especificación, la mayoría de las cámaras digitales la siguen para administrar el almacenamiento de archivos: https://en.wikipedia.org/wiki/Camera_Image_File_Format

Esencialmente, se crea una carpeta, como 000OLYMPUSy se agregan fotos a esa carpeta (por ejemplo DSC0000.RAW). Cuando el contador de nombre de archivo alcanza DSC9999.RAWuna nueva carpeta se crea ( 001OLYMPUS) y la imagen se agrega nuevamente, restableciendo el contador, posiblemente con un prefijo diferente (ej P_0000.RAW.:).

Alternativamente, también podría crear carpetas basadas en partes del nombre del archivo (ya mencionado varias veces). Por ejemplo, si su foto tiene nombre IMG_A83743.JPG, guárdela en IMG_\A8\3\IMG_A83743.JPG. Es más complicado de implementar, pero hará que sus archivos sean más fáciles de encontrar.

Dependiendo del sistema de archivos (esto requerirá un poco de investigación), es posible que pueda volcar todas las imágenes en una sola carpeta, pero, en mi experiencia, esto generalmente causaría problemas de rendimiento.


0

Es posible que desee ver ZFS (sistema de archivos, administrador de volúmenes de Sun) Saludos


0

¡Una manera limpia de generar el camino a partir de un gran número es convertirlo fácilmente en hexadecimal y luego dividirlo!

por ejemplo 1099496034834> 0xFFFF1212>FF/FF/12/12

public string GeneratePath(long val)
{  
    string hex = val.ToString("X");
    hex=hex.PadLeft(10, '0');
    string path="";
    for(int i=0; i<hex.Length; i+=2 )
    {
        path += hex.Substring(i,2);
        if(i+2<hex.Length)
            path+="/";
    }
    return path;
}

Almacenar y cargar:

public long Store(Stream doc)
{
   var newId = getNewId();
   var fullpath = GeneratePath(newId)
   // store into fullpath 
   return newId;
}

public Stream Load(long id)
{
   var fullpath = GeneratePath(newId)
   var stream = ... 
   return stream;
}

Códigos fuente completos: https://github.com/acrobit/AcroFS


-1

Desafortunadamente, los sistemas de archivos son muy malos (rendimiento con muchos archivos por directorio o árboles de directorios profundos, comprobación de tiempos de reinicio, confiabilidad) en la administración de muchos archivos pequeños, por lo que la solución anterior que involucra archivos ZIP es mejor si desea usar un sistema de archivos.

Usar un administrador de base de datos es, con mucho, la mejor opción; uno simple como BDB o GDBM por ejemplo; Incluso un DBMS relacional como MySQL sería mejor. Solo las personas perezosas que no entienden los sistemas de archivos y las bases de datos (por ejemplo, aquellos que descartan las transacciones) tienden a utilizar los sistemas de archivos como bases de datos (o algo más raro, viceversa).


-2

¿Qué tal una base de datos con una tabla que contiene una ID y un BLOB para almacenar la imagen? Luego, puede agregar nuevas tablas cada vez que desee asociar más elementos de datos con una foto.

Si espera escalar, ¿por qué no escalar ahora? Ahorrará tiempo tanto ahora como luego en la OMI. Implemente la capa de base de datos una vez, lo cual es bastante fácil de comenzar. O implemente algo con carpetas y nombres de archivo y bla, bla, bla, y luego cambie a otra cosa cuando comience a volar MAX_PATH.


55
He estado allí, hecho eso, tengo las cicatrices para probarlo. Las bases de datos que almacenan imágenes en grandes cantidades son irritables casi sin creerlo y requieren cantidades excesivas de mantenimiento. Mucho mejor para almacenarlos en el sistema de archivos a menos que tenga una necesidad específica que sólo puede ser respondida por una base de datos (la nuestra era el seguimiento de versiones.)
Satanicpuppy

1
Y hay muchas utilidades para manejar archivos y sistemas de archivos, pocas o ninguna para manejar archivos dentro de una base de datos.
Mark Ransom

2
Oh Dios No. Por favor, no use una base de datos como gran almacenamiento BLOB.
Neil N

Eek No sabía que las bases de datos (¿todavía?) Tienen tantos problemas con los BLOB.

¿Cómo puede una solución tan mala que tiene tantos comentarios todavía tener un +1? sin ofender al OP (veo que vino de SO) pero el botón de voto negativo está aquí por una razón.
Mark Henderson
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.