2009-08-10 8 views
7

Tengo un proceso que inicialmente generará 3-4 millones de archivos PDF y continuará a una velocidad de 80 K/día. Serán bastante pequeños (50K) cada uno, pero lo que me preocupa es cómo administrar la masa total de archivos que estoy generando para facilitar la búsqueda. Algunos detalles:La mejor manera de almacenar/recuperar millones de archivos cuando sus metadatos están en una base de datos SQL

  1. Voy a tener algunos otros pasos para ejecutar una vez que se haya generado un archivo, y habrá algunos servidores participantes, por lo que tendré que vigilar los archivos a medida que se generan.
  2. Una vez generados, los archivos estarán disponibles a través de un proceso de búsqueda que he escrito. Esencialmente, tendré que extraerlos en función de un número de pedido, que es único por archivo.
  3. En cualquier momento, se puede reenviar un número de pedido existente, y el archivo generado deberá sobrescribir la copia original.

Originalmente, había planeado escribir estos archivos en un solo directorio en un NAS, pero me doy cuenta de que esto podría no ser una buena idea, ya que hay millones y Windows podría no manejar un millón de archivos -Parece muy elegante. Estoy buscando algunos consejos:

  1. ¿Está bien una sola carpeta? Los archivos nunca aparecerán en la lista; solo se recuperarán utilizando un System.IO.File con un nombre de archivo que ya he determinado.
  2. Si hago una carpeta, ¿puedo buscar nuevos archivos con un System.IO.DirectoryWatcher, incluso con tantos archivos, o empezará a ser lento con tantos archivos?
  3. ¿Deberían almacenarse como BLOB en una base de datos de SQL Server? Como tendré que recuperarlos por un valor de referencia, tal vez esto tenga más sentido.

¡Gracias por tu opinión!

+1

usted tiene que generar a todos ellos ¿frente? ¿Puedes generarlos bajo demanda? ¿Quizás incluso los genere a pedido cada vez que los necesite, para que no tenga que almacenar los archivos? Obviamente, los datos de los que se generan están almacenados en algún lugar, entonces, ¿por qué duplicarlos? – rmeador

+0

Los informes tardan unos 5 segundos en generar, pero contienen algunas instantáneas de cómo están las cosas ahora (algunos términos de contrato), por lo que no se pueden generar a pedido (podría almacenar el historial y hacerlo de esa manera, pero legal nos ha aconsejado que los necesitamos todos desde el principio, ya que los términos del contrato a pedido, que podrían haber cambiado, los pusieron nerviosos). – SqlRyan

+2

Simplemente genere a pedido. Almacene la instantánea y llévela "generada" a legal. Es por eso que no dejas que las personas entiendan los detalles de lo que haces. Solo asegúrate de que el resultado es el que desean y gestiona los detalles tú mismo. De esta forma, puede generar material a pedido si el resultado es el mismo. – Pyrolistical

Respuesta

3

Agruparé los archivos en subcarpetas específicas y trataré de organizarlas (las subcarpetas) de alguna manera lógica de negocios. ¿Quizás todos los archivos hechos durante un día determinado? Durante un período de seis horas de cada día? O cada número de archivos, diría unos 1000 como máximo. (Probablemente haya un número ideal, ojalá alguien lo publique).

¿Los archivos envejecen y se eliminan? Si es así, clasifique y archive el fragmento eliminable. Si no, ¿puedo ser su proveedor de hardware?

Hay argumentos en ambos lados para almacenar archivos en una base de datos.

  • Por un lado, se obtiene una mayor seguridad, porque es más difícil extraer los archivos del DB; por otro lado, obtiene un rendimiento potencialmente peor, porque es más difícil extraer los archivos del DB.
  • En la base de datos, no tiene que preocuparse por la cantidad de archivos por carpeta, sector, grupo NAS, lo que sea, ese es el problema de la base de datos, y probablemente tengan una buena implementación para esto. Por otro lado, será más difícil administrar/revisar los datos, ya que sería una cantidad de miles de millones en una sola tabla y, bueno, asco. (Podría dividir la tabla en función de la lógica empresarial antes mencionada, lo que haría infinitamente más fácil la eliminación o el archivado. Eso, o quizás particiones de vistas, ya que el particionado de tablas tiene un límite de 1000 particiones).
  • Servidor SQL 2008 tiene el tipo de datos FileStream; No sé mucho sobre eso, podría valer la pena investigarlo.

Un último punto de qué preocuparse es mantener los datos "alineados". Si el DB almacena la información en el archivo junto con la ruta/nombre del archivo, y el archivo se mueve, puede ser totalmente regado.

4

para responder a sus preguntas:

  1. no me almacenarlos en una sola carpeta. Como en algún momento es probable que quiera ver los archivos reales en el disco, en lugar de hacerlo de otra manera.
    En lugar ¿por qué no almacenarlos en directorios separados, divididos en lotes de 1000? Posiblemente usando el ID como clave.
  2. Que muchos archivos probablemente inundarán el DirectorWatcher, por lo que se perderán algunos. Lo he usado en el pasado, y pasado un cierto punto (unos cien), he descubierto que empieza a perder archivos. Posiblemente use un directorio diferente para los archivos entrantes, y luego procese esto cada cierto tiempo. Esto puede disparar un proceso para actualizar el original.
  3. No almacenaría los documentos en una base de datos, pero definitivamente almacenaría los metadatos en una base de datos.
+0

# 2 era algo a lo que tenía miedo: los archivos no se generarán demasiado rápido (mi proceso de generación solo manejará de 10 a 20 en una tiempo, y espero obtener un nuevo archivo aproximadamente una vez/segundo), pero aún así pensé que el observador podría portarse mal en algún momento. – SqlRyan

+0

Si tiene SQL Server 2008, busque en el n. ° 3 y almacene todo en la base de datos, con el archivo como FILESTREAM. De esta forma, puede asegurarse de que el DB nunca se desincronice con el sistema de archivos. http://technet.microsoft.com/en-us/library/bb933993.aspx – user7116

0

Pregunta:

¿Por qué estos documentos deben ser generados y almacenados como archivos PDF?

Si se pueden generar, ¿por qué no mantener los datos en la base de datos y generarlos sobre la marcha cuando sea necesario? Esto significa que puede buscar los datos reales que se requieren para buscar de todos modos y no tener los archivos en el disco. De esta manera, también puede actualizar la plantilla PDF cuando sea necesario sin la necesidad de regenerar nada.

+1

Son contratos con firmas electrónicas, y legal nos ha dicho que no podemos generarlos sobre la marcha, por lo que está fuera :(Incluso además eso, nos gustaría que el sistema sea tan receptivo como sea posible, y recuperar una copia es, con suerte, más rápido que hacer una. – SqlRyan

0

1) Esto va totalmente en contra de lo que suelo predicar, pero es posible que desee almacenarlos en una base de datos SQL ya que son trully archivos pequeños. SQL Server también le permite encontrar rápida y fácilmente los archivos que necesita sin ningún daño en disco loco normalmente asociado con la enumeración de un directorio tan grande. Además, almacenar los archivos en SQL (aunque generalmente estoy en contra) facilitaría enormemente el proceso de copia de seguridad/restauración.

2) tienda a todos en directorios y, o bien con el índice de servicio de las ventanas de indexación ( escalofríos) o crear su propio índice en SQL Server que contendrá el nombre del archivo y la ruta completa. Sugiero almacenarlos en directorios separados, con solo unas pocas decenas de miles de archivos cada uno. Tal vez podrías usar el año de la orden como el nombre de la carpeta?

Independientemente de cómo almacenan - no escanear el directorio para encontrar los archivos - definitivamente tendrá que tener un índice de algún tipo.

Espero que esto ayude!

+0

Voy a mantener los metadatos en una base de datos segura: no escanearé la carpeta, ya que eso también me dio escalofríos. Solo quería ver si hay algún proceso que se asfixie con carpetas tan grandes. – SqlRyan

1

Determine el orden lógico de los subdirectorios y guárdelos en bloques de no más de 512 archivos en una carpeta.

No guarde los archivos en una base de datos. Las bases de datos son para datos, los servidores de archivos son para archivos. Guárdelos en un servidor de archivos, pero almacene la ruta y la información de recuperación en una base de datos.

+0

Sé que en los días de DOS, 512 era un "número mágico" para los archivos en los directorios. ¿Todavía se aplica? –

+0

Encontré esta respuesta - http://stackoverflow.com/questions/671260/tips-for-managing-a-large-number-of-files/671273#671273 - ¿Es eso lo que defiendes? – SqlRyan

+0

MS SQL Server puede no ser la mejor base de datos para almacenar archivos, sin embargo, SecureFiles de Oracle en 11g funciona como se anuncia y muy bien. Me imagino que MS recogerá este tipo de tecnología pronto de su lado, anulando el mantra anterior de "no hay archivos en una base de datos". – user7116

0

Mi base de datos de archivos contiene más de 4 millones de carpetas, con muchos archivos en cada carpeta.

Acabo de lanzar todas las carpetas en un directorio. NTFS puede manejar esto sin ningún problema, y ​​las herramientas avanzadas como robocopy pueden ayudarlo cuando necesite moverlo.

Solo asegúrate de que puedes indexar los archivos sin escanear. Lo hice lanzando mi índice en una base de datos mysql.

Para obtener un archivo, busco en la base de datos mysql algunos metadatos y obtengo un índice. Luego uso este índice para leer el archivo directamente. Escalado bien para mí hasta ahora. Pero tenga en cuenta que va a convertir todo en acceso aleatorio y, por tanto, lectura/escritura aleatoria. Este es un rendimiento pobre para HDD, pero afortunadamente SSD ayudará mucho.

Además, no arrojaría los archivos a la base de datos mysql. No podrá hacer lecturas de red sin tener un cliente que entienda mysql. Ahora mismo puedo acceder a cualquier archivo a través de la red usando cualquier programa porque puedo usar su URL de red.

2

1) Una carpeta simple puede ser aceptablemente rápida con un índice separado, pero como es trivial colocarla en subdirectorios que permitan la habilidad de navegar simplemente haz eso.
Así que ahora tiene que descubrir su convención de nomenclatura. Aunque normalmente sugiero un hash para obtener una distribución uniforme de los ID, pero como estás haciendo mucho, probablemente tenga sentido utilizar los valores que ya obtuviste. Si tiene un número de orden, ¿tiene también una marca de tiempo? Si es así, simplemente prefija el número de orden con una marca de tiempo.

Sólo ten en cuenta que si usted está utilizando ID de compra puede experimentar http://en.wikipedia.org/wiki/Benford%27s_law

+0

+1 por la ley de Benford, eso es fascinante. – SqlRyan

+0

La ley de Benford, mi interpretación: hay más comienzos que fines. O, más ampliamente, más comienzos que finales. Muy cierto, creo. – Beth

2

Usted puede organizar fácilmente archivos en varias carpetas sin tener que hacer esto mediante la lógica de negocio, o una orden por día, lo cual es especialmente bueno si ese tipo de pedido sería 'clumpy' (muchos hits en una carpeta, pocos en otros).

La forma más sencilla de hacerlo es crear un hash único para el nombre del archivo, por lo que tal vez se obtiene algo como esto:

sf394fgr90rtfofrpo98tx.pdf 

partirlo en bloques de dos caracteres, y usted consiga esto:

sf/39/4f/gr/90/rt/fo/fr/po/98/tx.pdf 

Como puede ver, le da un árbol de directorio profundo que puede navegar fácilmente.

Con una buena función hash, esta se distribuirá de manera muy uniforme, y nunca obtendrá más de 1296 entradas por directorio. Si alguna vez se produce una colisión (que debería ser extremadamente rara), simplemente agregue un número hasta el final: tx.pdf, tx_1.pdf, tx_2.pdf. Una vez más, las colisiones en hashes tan grandes deberían ser extremadamente raras, por lo que el tipo de agrupamiento que se produce a causa de esto no es un problema.

Dijiste que los documentos están firmados digitalmente, por lo que probablemente tengas el hash que necesitas justo en la forma de la cadena de firma.

1

Necesita probarlo. Todas estas soluciones dependen del sistema de archivos subyacente. Algunos sistemas de archivos pueden manejar grandes directorios, otros no. Algunos sistemas de archivos indexan sus directorios, otros no (estos dos puntos no están necesariamente relacionados).

Romper las cosas en un árbol de directorios tiene posibilidades razonables de ser eficaz, simplemente porque, al final, los directorios individuales tienden a tener pocas entradas en general.Eso funciona para la mayoría de los sistemas de archivos, simplemente porque incluso un "estúpido" que está haciendo una búsqueda de directorio lineal para su archivo puede buscar un par de cientos de entradas razonablemente rápido.

Si el sistema de archivos está indexando los directorios (como, por ejemplo, un btree o simplemente ordenándolo internamente, que efectivamente es lo mismo en este contexto), los tamaños de directorio son menos importantes, aunque algunas herramientas pueden quejarse (cargando una ventana del Explorador de Windows con archivos 4M, que saben lo que sucederá).

Por lo tanto, me gustaría investigar su sistema operativo planificado y las opciones del sistema de archivos, y probarlo y ver cuál funciona mejor para usted.

1

Por qué no considerar Almacenamiento de todos esos archivos después convertidas en PDF en la base de datos (BLOB) De ahí Ventajas:

  1. que creo que no tendrá que hacer frente direclty de con el sistema operativo de E/S, y dejar todo hasta la base de datos.
  2. No hay necesidad de hash de nombrar
  3. Fácil de copia de seguridad y mantener
0

Creo que al igual que muchos otros han dicho, que debe hacer subcarpetas, pero de una manera que se pueden encontrar los datos a través de código. Por ejemplo, si datetime funciona, úselo. Al leer lo que dijo, parecería que hay algún tipo de estructura jerárquica para los informes (diario, semanal, diario X, Y por hora, etc.). Observaría la estructura de cuándo y por qué los informes se generan y construye. mis directorios de esa manera.

1

Al usar una base de datos para almacenar sus archivos, especialmente con archivos pequeños, la sobrecarga debe ser pequeña. pero también se puede hacer cosas como:

DELETE FROM BLOBTABLE WHERE NAME LIKE '<whatever>' 

o cuando se tiene una fecha de caducidad, o desea actualizar un archivo, y eliminar por:

DELETE FROM BLOBTABLE WHERE CREATIONDATE < ... 
etc... 
Cuestiones relacionadas