Mappés en mémoire MappedByteBuffer ou Direct ByteBuffer DB pour la mise en Œuvre?

Ce qui ressemble à une longue question, parce que de tout le contexte. Il y a 2 questions à l'intérieur du roman ci-dessous. Merci d'avoir pris le temps de lire ceci et de fournir de l'aide.

Situation

Je suis en train de travailler sur une solution évolutive de la banque de données de mise en œuvre qui peuvent soutenir le travail avec les données des fichiers de quelques KO à une TUBERCULOSE ou plus dans la taille de 32 bits ou 64 bits du système.

La banque de données utilise une Copie sur Écriture de conception; toujours en ajoutant les données nouvelles ou modifiées à la fin du fichier de données et de ne jamais en place des modifications à des données existantes.

Le système peut héberger 1 ou plusieurs bases de données; chaque représenté par un fichier sur disque.

Les détails de la mise en œuvre ne sont pas importants; le seul détail important étant que j'ai besoin de constamment s'ajouter au fichier et de les pousser à partir de KO, de MB, GB à la TUBERCULOSE, alors que dans le même temps de façon aléatoire à sauter autour du fichier pour les opérations de lecture pour répondre à des demandes de clients.

Premier Pensées

À première vue, je savais que je voulais utiliser des fichiers mappés en mémoire, donc je pourrais pousser le fardeau de la gestion efficace de l'état en mémoire des données sur l'OS hôte et hors de mon code.

Alors tout mon code doit vous inquiéter, c'est la sérialisation de l'ajouter à des opérations de fichier en écriture, et en permettant à n'importe quel nombre de lecteurs simultanés à chercher dans le fichier de répondre à la demande.

Conception

Parce que l'individu fichiers de données peut croître au-delà de la limite de 2 go de MappedByteBuffer, j'attends que ma conception devra inclure une couche d'abstraction qui prend une écriture de décalage et les convertit en un offset à l'intérieur d'un groupe spécifique de 2 GO segment.

So far So good...

Problèmes

C'est là que j'ai commencé à avoir raccroché et pense que le fait d'aller avec un design différent (proposé ci-dessous) pourrait être la meilleure façon de le faire.

De la lecture à travers 20 "mappés en mémoire" liées à des questions ici, et il semble mmap appels sont sensibles à vouloir contiguë pistes de mémoire lorsqu'ils sont affectés. Ainsi, par exemple, sur un 32 bits de l'OS hôte si j'ai essayé de mmap un fichier de 2 go, en raison de la fragmentation de la mémoire, mes chances sont minces que la cartographie de succès et au lieu de cela je dois utiliser quelque chose comme une série de 128 mo de mappages de tirer un ensemble de fichier.

Quand je pense que le design, et même en utilisant une 1024MB mmap tailles, pour un SGBD hébergement de quelques énormes bases de données de toutes représentées par me dire de 1 to fichiers, j'ai maintenant milliers de mappés en mémoire les régions dans la mémoire et dans mes propres tests sur Windows 7 essayez de créer quelques centaines de mmaps sur un multi-GO fichier, je n'ai pas tout simplement courir dans les exceptions, J'ai effectivement eu la JVM d'erreur à chaque fois que j'ai essayé d'allouer trop et dans un cas obtenu la vidéo dans mon Windows 7 machine à couper et re-initialiser avec un OS-erreur-popup je n'ai jamais vu avant.

Indépendamment de l'argument de "vous n'aurez jamais susceptibles de traiter les fichiers de grande taille" ou "ceci est un exemple artificiel", le fait que je pouvais le code quelque chose comme ça avec ce genre d'effets secondaires mis mon alarme interne en état d'alerte maximale et le fait d'envisager une alternative impl (ci-dessous).

En plus de cette question, ma compréhension de fichiers mappés en mémoire, c'est que je dois re-créer le mapping chaque fois que le fichier est cultivé, donc dans le cas de ce fichier en ajout seulement dans la conception, littéralement cesse de croître.

Je peux lutter contre cette, dans une certaine mesure par la culture du fichier en morceaux (disons 8 MO à l'heure) et à re-créer le mapping chaque 8 MO, mais le besoin d'être constamment re-créer ces mappages a m'énerver surtout avec aucun explicite unmap fonctionnalité prise en charge par Java.

À la Question no 1 de 2

Compte tenu de l'ensemble de mes résultats jusqu'à ce point, je rejette fichiers mappés en mémoire comme une bonne solution pour principalement à lecture intensive des solutions ou en lecture seule des solutions, mais pas d'écrire-des solutions lourdes compte tenu de la nécessité de re-créer le mapping constamment.

Mais ensuite, je regarde le paysage autour de moi avec des solutions telles que MongoDB embrassant des fichiers mappés en mémoire tous sur la place et j'ai l'impression d'un manque certains composant de base ici (je sais que c'allocations dans quelque chose comme 2 GO étendues à un moment, donc j'imagine qu'ils travaillent autour de la ré-carte de coûts avec cette logique ET en aidant à maintenir la séquentiel s'exécute sur disque).

À ce point, je ne sais pas si le problème est de Java est l'absence d'un unmap opération qui rend ce beaucoup plus dangereux et inappropriés pour mes utilisations ou si ma compréhension est erronée et que quelqu'un peut me diriger vers le Nord.

Conception Alternative

Une autre conception de la mappé en mémoire de celui proposé ci-dessus que je vais aller avec si ma compréhension de mmap est correcte est comme suit:

Définir un direct ByteBuffer a un motif raisonnable de taille configurable (2, 4, 8, 16, 32, 64, 128 KO environ) ce qui le rend facilement compatible avec n'importe quelle plate-forme hôte (n'avez pas besoin de vous soucier de le SGBD lui-même provoquant l'écroulement des scénarios) et à l'aide de l'original FileChannel, effectuez spécifique-décalage de lit du fichier 1 tampon-capacité-morceau à la fois, complètement renoncer à des fichiers mappés en mémoire à tous.

L'inconvénient étant que mon code se soucier de choses comme "j'ai suffisamment lu depuis le fichier à charger le dossier complet?"

Un autre côté, c'est que je n'ai pas à faire usage de l'OS de la mémoire virtuelle logique, lui permettant de garder plus "chaud" en mémoire des données automatiquement pour moi; au lieu de cela, j'ai juste à espérer le fichier cache de la logique employée par le système d'exploitation est assez grand pour faire quelque chose d'utile pour moi ici.

La Question n ° 2 de 2

J'espérais obtenir une confirmation de ma compréhension de tout cela.

Par exemple, peut-être que le fichier cache est fantastique, que dans les deux cas (mappé en mémoire ou de diriger les lectures), le système d'exploitation hôte gardera comme beaucoup de mes chaud de données disponibles que possible, et la différence de performance pour les gros fichiers est négligeable.

Ou peut-être que ma compréhension de la nature sensible des exigences pour les fichiers mappés en mémoire (mémoire contiguë) sont incorrectes et que je peux ignorer tout cela.

  • Si vous avez gagné quelques aperçus depuis de poser votre question, merci de poster une réponse. Beaucoup de gens lisent cette question et qu'ils pourraient utiliser l'aperçu. Il ya une tonne de "ne pas corriger les" bugs entourant mmapping, comme bugs.sun.com/view_bug.do?bug_id=6893654 (bien que la JVM erreur de segmentation et de pilote graphique s'écraser sont encore pire!) Il est intéressant de voir comment un simple, élégant fonctionnalité native devient complexe et laid dans le monde géré.
  • vous êtes au bon endroit (à propos de l'élégant, de devenir inélégant) -- mon résultat final est que mmap ed fichiers n'ont pas pu être mis en place rapidement, sans introduire une grande instabilité dans le système (je ne sais pas si j'ai précisé dans ce fil, mais j'ai réussi à écran bleu de mon windows dev de la machine). Ce détail à lui SEUL me donne envie de coller à AsyncFileChannel utiliser pour les e/S de fichier et d'éviter mmap tous ensemble, bien que Peter (ci-dessous) a eu un succès important dans la Chronique.
  • Une fois que j'ai été en mesure d'apporter à la fois la VM et ma machine à genoux avec une apparente "mauvaise utilisation" de mmapped fichiers, j'ai été fait d'aller en bas de ce chemin. Elles sont élégantes et offrent des performances fantastiques, mais de plus la lecture que j'ai fait sur AsyncFileChannel il semble que vous pouvez obtenir à peu près la même performance (permettant à l'OS à utiliser le FS et le contrôleur de disque et d'e/S de commande pour optimiser les requêtes). Si vous voulez vraiment aller en bas de la mmap chemin, Peter est l'expert ici.
InformationsquelleAutor Riyad Kalla | 2012-02-13