2011-09-14 14 views
7

Necesito realizar operaciones cronológicamente en grandes series temporales implementadas como IList. Los datos finalmente se almacenan en una base de datos, pero no tendría sentido enviar decenas de millones de consultas a la base de datos.Implementación IList de archivo mapeado en memoria, para almacenar conjuntos de datos grandes "en la memoria"?

Actualmente, el IList en memoria desencadena una excepción OutOfMemory cuando intenta almacenar más de 8 millones de objetos (pequeños), aunque tendría que tratar con decenas de millones.

Después de algunas investigaciones, parece que la mejor manera de hacerlo sería almacenar datos en el disco y acceder a ellos a través de un contenedor IList.

Memory-mapped files (presentado en .NET 4.0) parece la interfaz correcta para usar, pero me pregunto cuál es la mejor manera de escribir una clase que debe implementar IList (para facilitar el acceso) y tratar internamente un archivo mapeado en memoria.

¡También tengo curiosidad por saber si conoce otras formas! Pensé, por ejemplo, en un contenedor IList utilizando datos de db4o (someone mentionned here usando un archivo mapeado en memoria como IoAdapterFile, aunque el uso de db4o probablemente agrega un costo de rendimiento frente a tratar directamente con el archivo mapeado en memoria).

Me he encontrado con this question pedido en 2009, pero no dio respuestas útiles o ideas serias.

+0

son las operaciones que realiza de forma secuencial? ¿o estás operando con todos los datos a la vez? – Yahia

+0

El acceso debe ser secuencial (iterar sobre la colección para realizar una actualización), y también necesito poder eliminar/eliminar objetos en el otro extremo. –

+2

Una base de datos es la herramienta adecuada para este trabajo. Actualice los datos en lotes para evitar demasiadas llamadas a la base de datos. También podría estar interesado en el procesamiento de estilo map-reduce para acelerar un poco las cosas. – dtb

Respuesta

8

Encontré este PersistentDictionary<>, pero solo funciona con cadenas de caracteres, y al leer el código fuente no estoy seguro de que haya sido diseñado para conjuntos de datos de gran tamaño.

Más escalable (hasta 16 TB), el ESENT PersistentDictionary<>, utiliza el motor de base de datos ESENT presente en Windows (XP +) y puede almacenar todos los objetos serializables que contengan tipos simples.

Disk Based Data Structures, including Dictionary, List and Array with an "intelligent" serializer era exactamente igual que lo que estaba buscando, pero no funcionaron satisfactoriamente con datos extremadamente grandes, especialmente en lo que no hace uso del "nativo" .NET MemoryMappedFiles todavía, y soporte para sistemas de 32 bits es experimental .

Actualización 1: Terminé la implementación de mi propia versión que hace un amplio uso de MemoryMappedFiles .NET; es muy rápido y probablemente lo lanzaré en Codeplex una vez que lo haya mejorado para usos más generales.

Actualización 2: TeaFiles.Net también funcionó muy bien para mi propósito. Muy recomendado (y gratis).

+0

Gracias por compartir sus experiencias. Me encuentro con el mismo problema y me pregunto si ya has publicado tu implementación en Codeplex o no. Gracias. – alhazen

+0

Hola, todavía no. Una restricción que tengo actualmente es que todos los objetos que se almacenan deben ser de tipos de valores. Si este es el caso para usted (o puede migrar del tipo de referencia a los tipos de valor) entonces puedo compartir mi código con usted antes de publicarlo en Codeplex. –

+0

@ErwinMayer Me pregunto si has compartido el código en alguna parte. Necesito una implementación de IList respaldada por archivos para algunos objetos grandes. –

1

Los archivos mapeados en memoria son una buena forma de hacerlo. Pero va a ser muy lento si necesita acceder a las cosas al azar.

Es probable que su mejor opción sea crear un tamaño de estructura fijo cuando se guarde en la memoria (si es posible) y luego usar el desplazamiento como la id del elemento de la lista. Sin embargo, eliminar/ordenar siempre es un problema.

+0

AFAIK, el acceso aleatorio debe ser O (1), dado que conocemos el desplazamiento de bytes. –

3

Veo varias opciones:

  • "in-memory-DB"
    por ejemplo SQLite se puede utilizar de esta manera - no hay necesidad de ningún tipo de configuración, etc. sólo distribuir la DLL (1 o 2) junto con la aplicación y el resto se puede hacer mediante programación
  • Cargar todos los datos en tablas temporales en la base de datos, con cantidades desconocidas (pero grandes) de datos Encontré que esto vale realmente rápido (y el procesamiento por lo general se puede hacer dentro del DB que es aún mejor!)
  • utilizar un archivo proyectado en memoria y un tamaño de estructura fija (acceso a matriz similar a través de offset), pero ten en cuenta que la memoria física es el límite excepto que utiliza una especie de "ventana deslizante" para mapear únicas partes en la memoria
Cuestiones relacionadas