Esta parece una pregunta larga, porque de todo el contexto. Hay 2 preguntas dentro de la novela a continuación. Gracias por tomarse el tiempo para leer esto y proporcionar asistencia.

Situación

Estoy trabajando en una solución escalable de almacén de datos de la aplicación que pueden apoyar el trabajo con archivos de datos de pocos KB de un TB o más en tamaño de 32-bits o 64-bit del sistema.

El almacén de datos utiliza un Copy-on-Write diseño; siempre añadiendo nuevos o modificados los datos al final del archivo de datos y nunca haciendo en lugar de modificaciones a los datos existentes.

El sistema puede alojar 1 o más de la base de datos; cada uno de ellos representado por un archivo en el disco.

Los detalles de la aplicación no son importantes; el único detalle importante es que me necesitan constantemente anexar al archivo y crecer a partir de KB, MB, GB a la TUBERCULOSIS, mientras que al mismo tiempo de forma aleatoria saltarse todo el archivo para operaciones de lectura para responder a las solicitudes de cliente.

Primera Pensamientos

A primera vista supe que quería usar archivos asignados en memoria para que yo pudiera empujar la carga de manera eficiente la gestión del estado en memoria de los datos en el sistema operativo del host y fuera de mi código.

Entonces todo mi código tiene que preocuparse es de serializar el append-to-operaciones de archivo en la escritura, y lo que permite que cualquier número de simultáneas a los lectores a buscar en el archivo para responder a las solicitudes.

Diseño

Porque el individuo archivos de datos puede crecer más allá del límite de 2 gb de un MappedByteBuffer, espero que mi diseño se tiene que incluir una capa de abstracción que lleva a un desplazamiento de escritura y la convierte en un desplazamiento en el interior de un determinado 2GB segmento.

Tan lejos y tan bien…

Problemas

Aquí es donde empecé a tener colgado y creo que va con un diseño diferente (que se propone a continuación) podría ser la mejor manera de hacer esto.

De la lectura a través de 20 o así «asignados a la memoria» de las preguntas relacionadas con aquí en por LO tanto, parece mmap llamadas son sensibles a querer contiguos de las carreras de la memoria cuando se asignan. Así, por ejemplo, en un host de 32 bits si OS traté de mmap un archivo de 2 gb, debido a la fragmentación de la memoria, mis posibilidades son escasas que la asignación tendrá éxito, y en lugar de que debo usar algo como una serie de 128 mb de asignaciones para tirar de todo un archivo en.

Cuando pienso que el diseño, incluso afirman que la utilización de 1024 MB mmap tamaños, para un DBMS acoger hasta un par de enormes bases de datos de todos los representados por decir de 1 tb de archivos, ahora tengo miles de memoria asignada a las regiones en la memoria y en mis propias pruebas en Windows 7 tratando de crear un par de cientos de mmaps a través de un multi-GB archivo, no me acaba de ejecutar en las excepciones, De hecho, me dieron la JVM violación de segmento cada vez que he intentado asignar demasiado y en un caso tienes el video en mi Windows 7 máquina para cortar y volver a inicializar con un OS-error-popup nunca he visto antes.

Sin importar el argumento de que «nunca te probabilidades de manejar archivos de gran tamaño» o «este es un ejemplo inventado», el hecho de que podía código de algo como de que con ese tipo de efectos secundarios poner mi alarma interna en alta alerta y de hecho se considera una alternativa impl (abajo).

ADEMÁS de ese problema, a mi entender de los archivos asignados en memoria es que tengo que volver a crear la asignación cada vez que el archivo se cultiva, por lo que en el caso de este archivo que es sólo anexar en el diseño, que es, literalmente, en constante crecimiento.

Puedo luchar contra esto en cierta medida por la creciente el archivo en trozos (digamos 8 MB en una hora) y sólo re-crear la asignación de cada una de 8MB, pero la necesidad de estar constantemente re-creación de estas asignaciones me tiene nervioso, especialmente con ninguna explícita desasignar característica soportada en Java.

La pregunta #1 de 2

Dado a todos mis conclusiones hasta este punto, me gustaría despedir a los archivos asignados en memoria como una buena solución, principalmente para leer pesados de soluciones o de sólo lectura soluciones, pero no escribir pesados de soluciones dada la necesidad de re-crear la asignación constantemente.

Pero entonces miro a mi alrededor en el paisaje que me rodea, con soluciones como MongoDB abrazando archivos asignados en memoria todo el lugar y me siento como una falta de algunos componentes básicos de aquí (yo sé que asignaciones en algo así como 2 gb de extensiones en un tiempo, así que me imagino que están trabajando en torno a la re-mapa de costo con esta lógica Y ayudando a mantener secuencial se ejecuta en el disco).

A este punto no sé si el problema es de Java de la falta de un desasignar operación que hace esto mucho más peligrosos e inadecuados para mi uso o si mi interpretación es incorrecta y alguien puede que me señale el Norte.

Alternativa De Diseño

Un diseño alternativo para la memoria asignada a una propuesta anterior que voy a ir con si mi comprensión de mmap es correcta es la siguiente:

Definir directa ByteBuffer de una razonable configurable tamaño (2, 4, 8, 16, 32, 64, 128 KB aproximadamente) por lo que es fácilmente compatible con cualquier plataforma de host (no necesita preocuparse acerca de los DBMS sí mismo causando paliza escenarios) y el uso de la original FileChannel, realizar específicos de compensación de lee del archivo 1 buffer-capacidad-fragmento del tiempo, completamente renunciar a los archivos asignados en memoria a todos.

La contracara de esto es que ahora mi código tiene que preocuparse de cosas como «¿he leído lo suficiente desde el archivo a cargar el registro completo?»

Otro lado es que no puedo hacer uso de el sistema operativo virtual de la memoria lógica, permitiendo que se mantenga más «caliente» de datos en-memoria para mí automáticamente; en su lugar sólo tengo la esperanza de que el archivo de caché de la lógica empleada por el sistema operativo es lo suficientemente grande como para hacer algo útil para mí aquí.

Pregunta #2 de 2

Tenía la esperanza de obtener una confirmación de mi comprensión de todo esto.

Por ejemplo, tal vez el archivo de caché es fantástico, que en ambos casos (asignado en memoria o en dirigir las lecturas), el sistema operativo del host mantendrá como mucho de mi caliente de datos disponibles como sea posible y la diferencia de rendimiento para archivos de gran tamaño es insignificante.

O tal vez mi comprensión de la sensible requisitos para los archivos asignados en memoria (memoria contigua) son incorrectas y puedo ignorar todo eso.

  • Si usted ha adquirido algunos conocimientos desde su pregunta, por favor, publicarlo como una respuesta. Un montón de gente lea esta pregunta y que podrían utilizar el conocimiento. Hay un montón de «no tiene arreglo» bichos » que rodea mmapping, como bugs.sun.com/view_bug.do?bug_id=6893654 (aunque JVM violación de segmento y el controlador de gráficos de estrellarse son aún peores!) Es interesante cómo un simple y elegante, a la función nativa se vuelve complejo y feo en el mundo administrado.
  • usted está exactamente correcto (sobre elegante convirtiendo poco elegante) — mis conclusiones es que mmap archivos no se pudo crear rápidamente sin introducir significativa inestabilidad en el sistema (no sé si he aclarado en este hilo, pero me las arreglé para la pantalla azul de la mi de desarrollo de windows de la máquina). Este detalle hizo que me quiere meter a AsyncFileChannel uso de e/S de archivos y evitar mmap todos juntos, aunque Pedro (abajo) ha tenido un éxito significativo en la Crónica.
  • Una vez que yo era capaz de llevar tanto la VM y mi maquina es de rodillas con la aparente «mal uso» de mmapped archivos, que se hizo con ir por ese camino. Son elegantes y ofrecen un rendimiento fantástico, pero a partir de la lectura más que yo hice en AsyncFileChannel parece que usted puede conseguir bastante cerca de el mismo rendimiento (lo que permite al sistema operativo para utilizar el FS y la controladora de disco y de I/O pedidos para optimizar las solicitudes). Si realmente quieres bajar el mmap camino, Pedro es el experto aquí.
InformationsquelleAutor Riyad Kalla | 2012-02-13

2 Comentarios

  1. 15

    Usted podría estar interesado en https://github.com/peter-lawrey/Java-Chronicle

    En eso estoy de crear varios mapas de memoria en el mismo archivo (el tamaño es una potencia de 2 hasta 1 GB), El archivo puede ser de cualquier tamaño (hasta el tamaño de su disco duro)

    También crea un índice así que usted puede encontrar cualquier registro al azar y cada registro puede ser de cualquier tamaño.

    Puede ser compartida entre procesos y se utiliza para una baja latencia eventos entre los procesos.

    Hago la suposición de que usted está usando un sistema operativo de 64 bits si desea utilizar grandes cantidades de datos. En este caso una Lista de MappedByteBuffer será todo lo que necesitas. Tiene sentido utilizar las herramientas adecuadas para el trabajo. 😉

    He encontrado desempeño muy bien, incluso con tamaños de datos de alrededor de 10 veces su tamaño de memoria principal (yo estaba usando una rápida unidad SSD para YMMV)

    • no se dan cuenta de que fueron la Crónica de un autor, gracias por la respuesta. ¿Cómo manejan la escritura en el archivo, es a través de la MBB o hacer que acaba de llamar a la FileChannel directamente y cada vez que una lectura op entra, fuera de los límites de la favorece MBB, sólo tiene que crear uno nuevo y añadirlo a su dataBuffers lista? Un núcleo detalle que me falta es lo que mucho de grandes archivos asignados a la del sistema operativo del host del uso de la memoria. (continuación en el siguiente comentario…)
    • puesto que no parece ser un requisito de «contiguo de memoria ram» cuando mem-asignación de un archivo, digamos que decidir sobre algo seguro como de 64 o 128 mb y como el archivo de base de datos crece y solicitudes de datos más allá de los existentes asignan límites acabo de crear más sobre la marcha. Entonces digamos que mi archivo de datos llega a 100s de la Egb y he 100s si no 1000 mem-asignada búferes de bytes… parece que voy a configurar mi ordenador para iniciar la paginación como un loco como VM se llena hasta el. Quiero ser consciente de gotcha-casos y desventajas es el meollo de lo que te estoy preguntando.
    • Cada archivo asignado en Memoria es un poco caro (no tengo datos exactos) sé si crear un montón de 1 MB de asignaciones de ejecutar fuera de los recursos con bastante rapidez. Sin embargo, si el uso de 1 GB de búferes puede crear un 8 TB de archivos. Usted puede determinar cuánto es demasiado para su sistema mediante la creación de un montón de pequeños (por ejemplo, 4 KB)
    • Hacer que los búferes demasiado grande no es un problema. Sólo se asigna a la memoria o disco las páginas que realmente uso. Esto significa que usted puede hacer un 1 GB de datos y el índice, pero hacer un du y encontrar su único uso de 8 KB. Así que la tentación es t a hacerlos tan grandes como sea posible. La desventaja es que la creación de ellos es caro (hay algún trabajo que es proporcional al tamaño de la asignación) Por esta razón que se me hace un moderado tamaño de 16 MB o 256 MB para reducir el golpe que se haya incurrido en un crecimiento.
    • He mirado en el cultivo de la asignación en un subproceso en segundo plano, mientras que mucho más rápido, he encontrado esto provoca errores de BUS. 🙁 Aparece de la asignación no puede ser usado de inmediato en un subproceso diferente a la que lo creó. Incluso liberar en un subproceso diferente pueden llevar a un accidente.
  2. 2

    Creo que usted no debe preocuparse acerca de mmap’ping archivos de hasta 2 gb de tamaño.

    Buscando en las fuentes de MongoDB como un ejemplo de DB haciendo uso de los archivos asignados en memoria encontrará siempre los mapas de datos en el archivo en MemoryMappedFile::mapWithOptions() (que llama a MemoryMappedFile::map()). DB de datos se extiende a través de múltiples archivos de hasta 2 gb de tamaño. También se preasigna archivos de datos, de modo que no hay necesidad de reasignar como los datos crece y esto impide la fragmentación de archivos. En general, usted puede inspirarte con el código fuente de este DB.

    • He actualizado los enlaces, pero creo que el código es bastante anticuado, MongoDB ha sufrido muchos cambios desde entonces.

Dejar respuesta

Please enter your comment!
Please enter your name here