Quelles sont mes options pour stocker et interroger d'énormes quantités de données répétées?

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

Question

J'évalue les options pour un stockage efficace des données en Java. L'ensemble de données est horodaté avec une clé primaire nommée. par exemple

Name: A|B|C:D
Value: 124
TimeStamp: 01/06/2009 08:24:39,223

Il peut s’agir d’un cours de bourse à un moment donné. Il s’agit donc, je suppose, d’un modèle classique de données chronologiques. Cependant, j'ai vraiment besoin d'une solution de SGBDR générique qui fonctionne avec toute base de données compatible JDBC raisonnable, car j'aimerais utiliser Hibernate. Par conséquent, les extensions de séries temporelles de bases de données comme Oracle ne sont pas vraiment une option, car je voudrais que l’implémenteur puisse utiliser sa propre base de données compatible JDBC / Hibernate.

Le défi consiste simplement en l’énorme volume de données qui peut s’accumuler en peu de temps. Jusqu'ici, mes implémentations étaient centrées sur la définition de calendriers de cumul et de purge périodiques dans lesquels les données brutes étaient agrégées dans des tableaux JOUR, SEMAINE, MOIS, etc. agrégats.

Le défi a des options limitées car il existe une limite absolue au nombre de données pouvant être physiquement compressées tout en conservant la granularité d'origine des données. Cette limite est exacerbée par la directive d'utilisation d'une base de données relationnelle et d'un gestionnaire JDBC générique. un à cela.

Empruntant un concept théorique d’algorithmes de compression de données classiques et tirant parti du fait que de nombreuses valeurs consécutives pour la même clé nommée peuvent être identiques, je me demande s’il est possible de réduire de manière transparente le nombre d’enregistrements stockés en les fusionnant. répéter les valeurs dans une ligne logique tout en stockant également un compteur qui indique, de manière efficace, que "les prochains n enregistrements ont la même valeur". L’implémentation de cela semble assez simple, mais l’inconvénient est que le modèle de données est maintenant extrêmement compliqué à interroger à l’aide de SQL standard, en particulier lors de l’utilisation de toute sorte de fonctions SQL agrégées. Cela réduit considérablement l'utilité du magasin de données, car seul un code personnalisé complexe peut restaurer les données vers un fichier "décompressé". résultant en une incompatibilité d'impédance avec des centaines d'outils qui ne pourront pas restituer correctement ces données.

J'ai envisagé la possibilité de définir des types personnalisés Hibernate qui "comprendraient" et "comprendreaient". l'ensemble de données compressées, puis sauvegardez-le et renvoyez les résultats de la requête avec les lignes synthétiques créées dynamiquement. (La base de données sera lue uniquement par tous les clients, à l'exception du flux d'entrée étroitement contrôlé). Plusieurs des outils que j'avais en tête intégreront Hibernate / POJOS en plus du fichier JDBC brut (par exemple, JasperReports). Toutefois, cela ne résout pas vraiment le problème des fonctions agrégées et présente probablement de nombreux autres problèmes.

Je suis donc en train de me résigner à devoir éventuellement utiliser un magasin de données plus propriétaire [éventuellement non-SQL] (toutes suggestions suggérées), puis à me concentrer sur la tâche peut-être moins complexe consistant à écrire un pseudo pilote JDBC pour au moins faciliter l'intégration avec des outils externes.

J'ai entendu parler de quelque chose appelé "" fichier compressé ". En tant que mécanisme permettant de réaliser cette compression de données, je ne connais aucune base de données fournissant ceci et la dernière chose que je veuille faire (ou que je puisse faire, vraiment ...) est d’écrire ma propre base de données.

Avez-vous des suggestions ou des idées?

Était-ce utile?

La solution

Je regarderais une base de données en colonnes . . Ce serait génial pour ce genre d’application

Autres conseils

Hibernate (ou n’importe quelle solution JPA) n’est pas le bon outil pour ce travail.

JPA / Hibernate n’est pas une solution légère. Dans les applications à volume élevé, les frais généraux sont non seulement importants mais prohibitifs. Vous devez vraiment vous pencher sur solutions de grille et de cluster . Je ne vais pas répéter l'aperçu des différentes technologies ici.

J'ai beaucoup d'expérience dans les systèmes d'information sur les marchés financiers. Quelques-unes des choses que vous avez dites me sont apparues:

  • vous avez beaucoup de données brutes;
  • vous souhaitez appliquer diverses agrégations à ces données (par exemple, des récapitulatifs quotidiens ouverts / supérieurs / inférieurs / proches);
  • La haute disponibilité est probablement un problème (c'est toujours le cas dans ce type de système); et
  • La faible latence est probablement un problème (idem).

Maintenant, pour les solutions de type grille / cluster, je les divise en deux catégories:

  1. Des solutions basées sur des cartes telles que Coherence ou Terracotta; et
  2. Des solutions basées sur Javaspaces, telles que GigaSpaces.

J'ai beaucoup utilisé Coherence et la solution Map peut être agréable, mais elle peut aussi être problématique. Les cartes de cohérence peuvent avoir des auditeurs et vous pouvez utiliser ce type de choses pour faire des choses comme:

  • Alertes sur les prix du marché (les utilisateurs peuvent vouloir une notification lorsqu'un prix atteint un certain niveau);
  • Une tarification des produits dérivés (par exemple, un système de tarification des options négociées en bourse voudra procéder à une nouvelle révision du prix lorsqu'un titre sous-jacent change en dernier cours);
  • Un système d’appariement / de réservation peut vouloir faire correspondre les notifications d’opérations reçues aux fins de rapprochement;
  • etc.

Tout cela peut être fait avec les auditeurs, mais dans Coherence, par exemple, les auditeurs doivent être peu coûteux, ce qui conduit à des choses comme une Map ayant un auditeur, mais écrivant quelque chose dans une autre Map, qui peut être enchaînée pendant un certain temps. De plus, la modification de l'entrée du cache peut être problématique (bien qu'il existe des mécanismes pour traiter ce type de problème; je parle de situations telles que la désactivation d'une alerte de prix du marché pour qu'elle ne se déclenche pas une seconde fois).

J’ai trouvé les solutions de grille de type GigaSpaces bien plus intéressantes pour ce type d’application. L’opération de lecture (ou de lecture destructive) est une solution extrêmement élégante et évolutive. Vous pouvez obtenir des mises à jour transactionnelles de la grille avec des performances inférieures à la milliseconde.

Considérez les deux architectures de file d'attente classiques:

  • Requête / Réponse: un message incorrect peut bloquer la file d'attente et de nombreux expéditeurs et destinataires (pour l’évolutivité), l’augmentation du nombre de canaux n’est pas toujours simple; et
  • Publish / Subscribe: cela sépare l'expéditeur et le destinataire, mais manque d'évolutivité, car si vous avez plusieurs abonnés, ils recevront chacun le message (pas nécessairement ce que vous voulez avec un système de réservation par exemple).

Dans les GigaSpaces, une lecture destructive ressemble à un système de publication / abonnement évolutif et une opération de lecture est similaire au modèle de publication / abonnement traditionnel. Une implémentation Map et JMS est construite au-dessus de la grille et permet d'effectuer la commande FIFO.

Maintenant, qu'en est-il de la persistance, je vous entends demander? La persistance est une conséquence du choix de tous les autres problèmes. Pour ce type d’application, j’aime bien la Persistance en tant que service modèle (écrit ironiquement à propos de Hibernate mais il ne s'applique à rien).

En gros, cela signifie que les hits de votre magasin de dates sont asynchrones et que cela fonctionne bien avec le traitement des données récapitulatives. Comme si vous pouviez avoir un service à l'écoute des notifications d'échange et ne conserver que ceux qui l'intéressaient (agrégation en mémoire si nécessaire). Vous pouvez faire les prix d'ouverture / haut / bas / fermeture de cette façon.

Pour les données volumineuses, vous ne voulez pas vraiment tout écrire dans la base de données. Pas de façon synchrone quand même. Un magasin persistant et un entrepôt de données est probablement la route que vous souhaitez utiliser, mais cela dépend des exigences, des volumes, etc.

.

C’est un sujet compliqué et je n’ai vraiment qu’à le toucher. J'espère que cela vous aide.

Vous trouverez probablement intéressant d’écouter la la présentation de Michael Stonebraker à Money: Tech . Il aborde un certain nombre de choses dont vous avez besoin et il montre comment les trois grands éléphants (SQL Server, Oracle et DB2) ne pourront jamais répondre aux besoins des magasins de ticks (que vous construisez semble-t-il). Il creuse au-delà des magasins de colonnes, ce qui, je le reconnais, est la bonne direction. Il discute même de la compression et de la vitesse, deux problèmes qui vous concernent.

voici d'autres liens que vous pouvez trouver intéressants:

De nombreux systèmes de gestion de base de données compatibles JDBC (par exemple Oracle) fournissent une compression dans le moteur de stockage physique. Oracle, par exemple, a la notion de "compressé" table sans surcharge de décompression:

http: //www.ardentperf .com / wp-content / uploads / 2007/07 / advanced-compression-datasheet.pdf

Merci pour les réponses.

Cletus, j’apprécie les grandes lignes, mais je n’arrive pas à faire un compromis en abandonnant la flexibilité des bases de données et la compatibilité avec JDBC / Hibernate pour permettre l’utilisation de tous les outils disponibles. De plus, bien que je ne l'aie pas clairement indiqué, je ne veux pas forcer mes utilisateurs à adopter une solution commerciale [éventuellement coûteuse]. S'ils ont la marque de base de données X, laissez-les l'utiliser. S'ils ne s'en soucient pas, nous recommandons Open Source Database Y. Fondamentalement, l'application a plusieurs visages, l'un d'entre eux étant un référentiel pour les données entrantes, mais un autre visage est une source de génération de rapports et je vraiment don ne voulez pas vous lancer dans la rédaction de générateurs de rapports.

Bien que je ne l'aie pas encore testé, je suis très impressionné par LucidDB . Il s'agit d'une base de données orientée colonne qui fournit de bonnes performances de requête et une compression apparemment bonne des données. Il a un pilote JDBC, bien qu’aucun dialecte Hibernate n’existe pour le moment, à ce que je sache. Il prend également en charge les transformations définies par l'utilisateur qui, en bref, me permettront de mettre en œuvre mon idée de compresser les valeurs répétitives et consécutives dans une "ligne", mais de les supprimer en plusieurs "synthétiques". lignes au moment de la requête, le tout fait de manière invisible à l’appelant de la requête. Enfin, il prend en charge cette fonctionnalité astucieuse des tables étrangères dans laquelle d'autres tables de base de données prenant en charge JDBC peuvent être frontées dans LucidDB. Je pense que cela peut être précieux pour fournir un certain niveau de support pour d'autres bases de données.

Merci pour le pointeur, Javaman. Il m'a zoné sur LucidDB.

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