¿MappedByteBuffer con asignación de memoria o Direct ByteBuffer para la implementación de DB?

Esto parece una pregunta larga debido a todo el contexto. Hay 2 preguntas dentro de la novela a continuación. Gracias por tomarse el tiempo de leer esto y brindar asistencia.

Situació

Estoy trabajando en una implementación de almacén de datos escalable que puede admitir el trabajo con archivos de datos de unos pocos KB a un TB o más de tamaño en un sistema de 32 bits o 64 bits.

El almacén de datos utiliza un diseño de Copia en escritura; siempre agregando datos nuevos o modificados al final del archivo de datos y nunca haciendo ediciones in situ a los datos existentes.

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

Los detalles de la implementación no son importantes; el único detalle importante es que necesito agregar constantemente al archivo y hacer que crezca de KB a MB, de GB a TB y, al mismo tiempo, saltear al azar el archivo para las operaciones de lectura para responder las solicitudes de los clientes.

Primeros pensamientos

primera vista, sabía que quería usar archivos mapeados en memoria para poder cargar la carga de administrar eficientemente el estado en memoria de los datos en el sistema operativo host y fuera de mi código.

Entonces, todo mi código tiene que preocuparme por serializar las operaciones de agregar a archivo en escritura y permitir que cualquier número de lectores simultáneos busque en el archivo para responder solicitudes.

Diseñ

Debido a que los archivos de datos individuales pueden crecer más allá del límite de 2 GB de un MappedByteBuffer, espero que mi diseño tenga que incluir una capa de abstracción que tome un desplazamiento de escritura y lo convierta en un desplazamiento dentro de un segmento específico de 2 GB.

Hasta aquí todo bien..

Problema

quí es donde comencé a colgarme y pensar que ir con un diseño diferente (propuesto a continuación) podría ser la mejor manera de hacerlo.

Desde la lectura de más de 20 preguntas relacionadas con "mapeo de memoria" aquí en SO, parece que las llamadas mmap son sensibles a querer corridas de memoria contiguas cuando se asignan. Entonces, por ejemplo, en un sistema operativo host de 32 bits si intenté mapear un archivo de 2GB, debido a la fragmentación de la memoria, mis posibilidades son escasas de que el mapeo tenga éxito y en su lugar debería usar algo como una serie de mapeos de 128 MB para extraer un archivo completo presentar en

Cuando pienso en ese diseño, incluso digo que usa tamaños de mmap de 1024 MB, para un DBMS que aloja algunas bases de datos enormes, todas representadas por archivos de 1 TB, ahora tengo miles de regiones mapeadas en memoria en la memoria y en mis propias pruebas en Windows 7 tratando de crear unos cientos de mmaps en un archivo de varios GB, no solo encontré excepciones, en realidad conseguí que la JVM se desconectara cada vez que intentaba para asignar demasiado y, en un caso, obtuve el video en mi máquina con Windows 7 para cortar y reiniciar con una ventana emergente de error del sistema operativo que nunca había visto antes.

Independientemente del argumento de "probablemente nunca manejarás archivos tan grandes" o "este es un ejemplo artificial", el hecho de que podría codificar algo así con ese tipo de efectos secundarios puso mi alarma interna en alerta máxima e hizo considerar una alternativa alternativa (a continuación).

demás de ese problema, mi comprensión de los archivos mapeados en memoria es que tengo que volver a crear el mapeo cada vez que el archivo crece, por lo que en el caso de este archivo que solo se agrega en diseño, literalmente crece constantemente.

Puedo combatir esto hasta cierto punto haciendo crecer el archivo en trozos (digamos 8MB a la vez) y solo recrear el mapeo cada 8MB, pero la necesidad de volver a crear constantemente estas asignaciones me pone nervioso, especialmente sin ninguna @ explíciunción @unmap compatible con Java.

Pregunta 1 de

Teniendo en cuenta todos mis hallazgos hasta este punto, descartaría los archivos mapeados en memoria como una buena solución principalmente para soluciones de lectura pesada o soluciones de solo lectura, pero no soluciones de escritura pesada dada la necesidad de volver a crear el mapeo constantemente .

Pero luego miro el paisaje que me rodea con soluciones como MongoDB que abarca archivos mapeados en memoria por todas partes y siento que me falta algún componente central aquí (sé que se asigna en extensiones de 2GB a la vez, así que me imagino que están trabajando alrededor del costo de reasignación con esta lógica Y ayudando a mantener ejecuciones secuenciales en el disco).

En este punto, no sé si el problema es la falta de Java de una operación de mapa que hace que esto sea mucho más peligroso e inadecuado para mis usos o si mi comprensión es incorrecta y alguien puede señalarme al Norte.

Diseño Alternativo

Un diseño alternativo al mapeado en memoria propuesto anteriormente con el que iré si mi comprensión de mmap es correcta es la siguiente:

Definira ByteBuffer directo de un tamaño configurable razonable (2, 4, 8, 16, 32, 64, 128 KB aproximadamente) lo que lo hace fácilmente compatible con cualquier plataforma de host (no tiene que preocuparse de que el DBMS en sí mismo cause escenarios de paliza) y use el FileChannel original , realiza lecturas de desplazamiento específico del archivo 1 buffer-capacity-chunk a la vez, renunciando por completo a los archivos mapeados en memoria.

La desventaja es que ahora mi código tiene que preocuparse por cosas como "¿Leí lo suficiente del archivo para cargar el registro completo?"

Otro inconveniente es que no puedo hacer uso de la lógica de memoria virtual del sistema operativo, lo que me permite mantener más datos "calientes" en la memoria para mí automáticamente; en cambio, solo tengo que esperar que la lógica de caché de archivos utilizada por el sistema operativo sea lo suficientemente grande como para hacer algo útil para mí aquí.

Pregunta # 2 de 2

Esperaba obtener una confirmación de mi comprensión de todo esto.

Por ejemplo, tal vez el caché de archivos sea fantástico, ya que en ambos casos (mapeo de memoria o lecturas directas), el sistema operativo host mantendrá la mayor cantidad de datos disponibles disponibles y la diferencia de rendimiento para archivos grandes es insignificante.

O tal vez mi comprensión de los requisitos sensibles para los archivos mapeados en memoria (memoria contigua) es incorrecta y puedo ignorar todo eso.

Respuestas a la pregunta(4)

Su respuesta a la pregunta