7
votes

Données graphiques persistantes (Java)

J'ai une application qui utilise des structures personnalisées graphique (arborestiques). Les structures ne sont pas de vrais arbres, mais à peu près tout est relié ensemble. La quantité de données est également grande (des millions de nœuds peuvent exister). Les nœuds d'arbres peuvent varier dans le type pour le rendre plus intéressant (héritage). Je ne veux pas modifier les structures de données pour accueillir le stockage de la persistance.

Je veux persister ces données sans trop de travail supplémentaire. J'ai goglé certaines options pour résoudre ce problème, mais je n'ai trouvé rien qui convient exactement à mes besoins. Options possibles: sérialisation, bases de données avec orm (hibernate?), JCR (Jackrabbit?), Autre chose?

performance est important, car il s'agit d'une application "en temps réel" basée sur une interface graphique (aucun traitement par lots) et il pourrait y avoir des millions de nœuds graphiques qui doivent être lus et écrits entre la mémoire et le magasin de données persisté.

Quelqu'un a-t-il quelqu'un d'expérience ou des idées sur stocker ce type de données?


3 commentaires

Je soupçonne qu'il est trop général pour donner une bonne réponse - pouvez-vous décrire certains cas d'utilisation pour la structure des arbres? C'est-à-dire comment il sera utilisé, quel que soit son stockage (si possible de dire). Pour la performance, vous voudrez peut-être dire à quel point les temps d'accès typiques sont rapides doivent être à Millis ou à une autre unité, car il suffit de dire que la performance et le «temps réel» est assez vague.


Quand "tout est connecté ensemble", ce n'est pas un arbre, c'est un graphique: en.wikipedia. org / wiki / graphique_% 28data_structure% 29 Peut-être que vous devriez reformuler le titre?


Bonne collection de bases de données de graphiques de haute performance actuelles: Java.dzone.com/news/laves -trendy-graphique-bases de données


6 Réponses :


2
votes

Étant donné que vous indiquez qu'il existe une grande quantité de données, vous voulez probablement un mécanisme que vous pouvez facilement apporter les données au besoin. La sérialisation n'est probablement pas très facile à manipuler avec de grandes quantités de données. Afin de la rompre dans des pièces gérables, vous auriez besoin d'utiliser des fichiers distincts sur le disque ou de les stocker ailleurs. JCR (Jackrabbit) est plus un système de gestion de contenu. Ceux-ci fonctionnent bien pour les objets de type «document». On dirait que les pièces individuelles de l'arbre que vous souhaitez stocker peuvent être petites mais ensemble, elles peuvent être grandes. Ce n'est pas une idée d'un CMS.

L'autre option que vous mentionnez, orm, est probablement votre meilleure option ici. Le JPA (API Java Persistence) est idéal pour faire ormer en Java. Vous pouvez écrire dans la spécification JPA et utiliser Hibernate, Eclipselink ou toute autre saveur du fournisseur de mois. Ceux-ci travailleront avec toute base de données que vous souhaitez. HTTP: // Java. Sun.com/javae/5/docs/api/index.html?javax/persistence/package-summary.html

L'autre avantage à JPA est que vous pouvez utiliser le paresseux FETCHTYPE pour charger des dépendances de l'arborescence. De cette façon, votre demande doit uniquement charger l'ensemble actuel de pièces qu'il travaille. Comme d'autres choses sont nécessaires, la couche JPA peut les récupérer de la base de données au besoin.


0 commentaires

1
votes

Un orj, par exemple en utilisant une API JPA (Hibernate, Eclipselink, ...) permettra probablement de mettre en œuvre une persistance très rapide. Les performances brutes de la persistance de l'arbre entier ont tendance à être délicate à atteindre par rapport à la LIME JDBC. Donc, si vos seuls critères de performance persistent dans l'arbre entier d'un coup, ce n'est probablement pas la meilleure option.
D'autre part, si vous devez également charger l'arborescence, synchroniser les modifications de l'arborescence, puis JPA offre à ces fonctionnalités intégrées avec (après un peu de modification) de meilleures performances que de nombreuses exécutions manuelles.

La sérialisation en Java a tendance à être assez lente et à produire des charges de données. La sérialisation est également assez fragile lorsque vous modifiez la classe dans votre application et est totalement inutile si vous devez synchroniser les changements d'arborescence.

Dans la même catégorie que la sérialisation, vous pouvez sérialiser en XML et la persister dans une base de données XML (Oracle XDB). Cependant, ceux-ci sont conçus plus pour la flexibilité de stockage / interrogation que la vitesse brute.

Si le temps n'est pas une préoccupation, le meilleur moyen est toujours d'impliquer un DBA compétent et de concevoir un datamodel optimal et de refacteur l'arbre en conséquence.


0 commentaires

2
votes

J'ai presque le problème exact et j'ai utilisé hibernate. Nous avons rencontré beaucoup de problèmes en retard dans le projet car la vue a essentiellement forcé le graphe entier dans la mémoire, même avec des types de récupération paresseux. Ces outils étaient bons tôt parce que nous pourrions rapidement obtenir un niveau de DB en place qui nous a donné quelque chose (Huzzah Agile). Seulement lorsque nous allions des améliorations de performance, avons-nous réalisé que nous devions écrire une couche de persistance plus intelligente.

est-il possible de faire du pré-traitement sur vos données? Si le problème est similaire, il y a beaucoup de valeur pour tenter de transformer les données en une forme intermédiaire plus proche de votre vue que le domaine d'origine et stockez cela dans la DB. Vous pouvez toujours revenir à la source d'origine à l'aide du type de récupération paresseux.

Fondamentalement, nous avons utilisé un système de 4 niveaux: Domaine DB, ViewModel-DB hybride (couche pré-transformée), ViewModel, vue

L'avantage de cette étape de pré-traitement (en particulier avec l'UI en temps réel), est que vous pouvez faire des données de page dans une vue de vue et le rendre gentiment. Voilà une grande quantité de performance dans une application en temps réel, restez simplement à la réactivité et de leur montrer quelque chose de gentil pendant qu'ils attendent. Dans notre cas, nous pourrions montrer des régions de boîtes 3D de données dans une pagination, les données liées à la chargement de données pourraient également afficher un indicateur visuel. L'hybride ViewModel-DB pourrait également faire de belles choses comme des files d'attente LRU adaptées à nos données de domaine. Le plus grand avantage était toutefois de supprimer la liaison directe. Les nœuds avaient quelque chose de similaire à l'URL à leurs données liées. Lorsque nous rendant nous pourrions rendre le lien, ou rendre qu'il y a un lien que nous partageons simplement la pagination en ce moment.

La persistance au niveau de la DB a été JPA (Hibernate) pour commencer, mais à la fin, les tables qu'elle sont générées pour notre structure d'héritage étaient terribles et difficiles à entretenir. En fin de compte, nous voulions plus de contrôle sur des tables que la JPA autorisées (ou au moins facilement autorisées). C'était une décision difficile en tant que JPA faisait une grande partie de la couche de DB facile. Puisque JPA a gardé des choses gentilles et pojo, cela n'avait pas besoin de chagriner avec nos datatypes. Donc c'était bien.

J'espère qu'il y a quelque chose que vous pouvez sortir de cette réponse sinueuse et bonne chance :)


0 commentaires

5
votes

Lorsque vos données utilisent une structure de données graphique (essentiellement: nœuds et bords / relations), une base de données graphique serait une très bonne correspondance. Voir ma réponse sur Les bases de données suivantes pour certains liens. Je fais partie du Projet de base de données NEO4J Open Source Graph, voir ce fil pour une discussion de celui-ci. Un grand avantage de l'utilisation de Neo4J dans un cas comme le vôtre est qu'il n'ya pas de difficulté à garder une trace d'objets persistants / activation ou la profondeur d'activation, ainsi que similaire. Vous n'avez probablement pas besoin de modifier les structures de données de votre application, mais bien sûr, un code supplémentaire serait nécessaire. Le Guide de conception donne un exemple de la manière dont votre code pourrait interagir avec la base de données.


0 commentaires

1
votes

envisagez de stocker vos nœuds dans une base de données, un schéma approprié peut être le suivant: xxx

puis utiliser jdbc pour accéder à / modifier les données. Si vous utilisez des index appropriés, il fonctionnera plutôt bien jusqu'à 100 millions d'enregistrements. mon sentiment d'intestin est d'éviter la sérialisation de l'objet générique si la performance est vraiment importante car vous perdez un certain contrôle sur les caractéristiques de performance du code avec ces solutions.

Si vous avez besoin de meilleures performances, vous pouvez utiliser un Memcached couche.


0 commentaires

0
votes

Je crois que la solution à votre problème consiste à utiliser TerreCotta comme mécanisme de stockage persistant. Je vous encourage à lire Cet excellent article à propos de le faire.

Il aborde vos deux principales préoccupations: performance et transparence . Il échoue facilement aux gros graphiques, tout en maintenant des performances élevées, en raison de son mécanisme de synchronisation efficace qui envoie uniquement des diffèmes d'instance sur le réseau. Il persiste également votre graphique de manière transparente car il fonctionne sur le niveau VM, vous absorbant du problème de décalage d'impédance que vous rencontreriez avec les alternatives mentionnées dans d'autres réponses (ORM ou OCM).

Pour être clair, la terre cuite est pas une solution de persistance pour chaque cas. Il est meilleur utilisé lorsque vous avez besoin de données disponibles sur les redémarrages de la machine et vous en avez besoin rapidement. Ce n'est pas une bonne solution lorsque vous avez besoin de ces données "archivées", par exemple ayant des exigences pour accéder à ces données longtemps après que le système d'exécution a cessé de fonctionner avec elle. Pensez aux commandes entrant dans un magasin Web. Vous voulez probablement stocker ces commandes pendant des années après leur accomplissement. Dans ces cas, vous pouvez consulter une approche hybride, où sélectionner des données à archiver peut être extraite du cluster en terre cuite et stockée à l'aide d'un SGBD traditionnel.

Pour un examen plus complet des avantages et des inconvénients, assurez-vous de lire Cet article sur Stackoverflow qui couvre plus de la minutie en faisant le choix.


0 commentaires