Java: Sérialisation d'une énorme quantité de données dans un seul fichier

StackOverflow https://stackoverflow.com/questions/129695

  •  02-07-2019
  •  | 
  •  

Question

Je dois sérialiser une énorme quantité de données (environ 2gigs) de petits objets dans un seul fichier pour pouvoir être traitées ultérieurement par un autre processus Java. La performance est un peu importante. Quelqu'un peut-il suggérer une bonne méthode pour y parvenir?

Était-ce utile?

La solution

Avez-vous consulté les tampons de protocole de Google? Cela ressemble à un cas d'utilisation.

Autres conseils

Je ne sais pas pourquoi la sérialisation Java a été rejetée, c'est un mécanisme parfaitement viable.

Ce n'est pas clair dans le message d'origine, mais est-ce que toutes les données 2G du tas sont en même temps? Ou êtes-vous en train de faire autre chose?

Hors de la boîte, la sérialisation n'est pas le "parfait" solution, mais si vous implémentez Externalizable sur vos objets, la sérialisation peut très bien fonctionner. La sérialisation des dépenses est de déterminer quoi écrire et comment l'écrire. En mettant en œuvre Externalizable, vous prenez ces décisions de ses mains, ce qui vous donne un coup de fouet en termes de performances et d'économies d'espace.

Bien que les E / S représentent le coût principal de l’écriture de grandes quantités de données, les coûts accessoires de la conversion des données peuvent également être très coûteux. Par exemple, vous ne voulez pas convertir tous vos numéros en texte et inversement, il est préférable de les stocker dans un format plus natif si possible. ObjectStream dispose de méthodes pour lire / écrire les types natifs en Java.

Si toutes vos données sont conçues pour être chargées dans une seule structure, vous pouvez simplement faire ObjectOutputStream.writeObject (yourBigDatastructure), après avoir implémenté Externalizable.

Cependant, vous pouvez également parcourir votre structure et appeler writeObject sur les objets individuels.

Dans les deux cas, vous aurez besoin de "objectToFile". routine, peut-être plusieurs. Et c’est effectivement ce que fournit Externalizable, ainsi qu’un cadre pour faire marcher votre structure.

L’autre problème, bien sûr, est la gestion des versions, etc. Mais puisque vous implémentez vous-même toutes les routines de sérialisation, vous avez également un contrôle total sur cela.

L’une des solutions les plus simples qui me viennent immédiatement à l’esprit est l’utilisation de la mémoire tampon mappée en mémoire de NIO (java.nio.MappedByteBuffer). Utilisez le tampon unique (environ) correspondant à la taille d'un objet et purgez-le / ajoutez-le au fichier de sortie si nécessaire. Les tampons mappés en mémoire sont très efficaces.

Avez-vous essayé la sérialisation java? Vous les écririez en utilisant un ObjectOutputStream.html" / et relisez-les en utilisant un ObjectInputStream . Bien entendu, les classes devraient être Sérialisable . Ce serait une solution simple et, comme les objets sont stockés en binaire, ce serait compact et rapide.

Si les performances importent beaucoup, vous devez écrire vous-même. Vous devriez utiliser un format binaire compact. Car avec 2 Go, le fonctionnement des E / S du disque est très important. Si vous utilisez un format lisible par l'homme, tel que XML ou d'autres scripts, redimensionnez les données avec un facteur de 2 ou plus.

En fonction des données, cela peut être plus rapide si vous compressez les données à la volée avec un taux de compression faible.

La sérialisation Java est totalement inutile. En lisant Java, vérifiez sur chaque objet s'il s'agit d'une référence à un objet existant.

J'ai développé JOAFIP comme alternative à la base de données.

Apache Avro pourrait également être utile. Il est conçu pour être indépendant de la langue et comporte des liaisons pour les langues populaires .

Découvrez-le.

tampons de protocole: cela a du sens. voici un extrait de leur wiki: http://code.google.com/apis /protocolbuffers/docs/javatutorial.html

Obtenir plus de vitesse

Par défaut, le compilateur de tampon de protocole essaie de générer des fichiers plus petits en utilisant la réflexion pour implémenter la plupart des fonctionnalités (analyse et sérialisation, par exemple). Cependant, le compilateur peut également générer un code optimisé explicitement pour vos types de message, fournissant souvent un gain de performances d'ordre de grandeur, mais doublant également la taille du code. Si le profilage indique que votre application passe beaucoup de temps dans la bibliothèque de tampons de protocole, essayez de modifier le mode d'optimisation. Ajoutez simplement la ligne suivante à votre fichier .proto:

option optimisation_pour = VITESSE;

Réexécutez le compilateur de protocole, il générera une analyse, une sérialisation et un code extrêmement rapides.

Vous devriez probablement envisager une solution de base de données. Toutes les bases de données optimisent leurs informations. Si vous utilisez Hibernate, vous conservez votre modèle objet tel quel et vous ne pensez même pas à votre base de données (je crois que c'est pourquoi elle s'appelle hiberner, stockez simplement vos données, puis ramenez-les)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top