2011-09-03 5 views
2

Je travaille sur la construction d'une application web qui se compose des utilisateurs procédant comme suit:Stockage de grands ensembles de données de niveau session?

  1. Parcourir et rechercher sur un serveur Solr contenant des millions d'entrées. (Cette partie de l'application fonctionne très bien.)

  2. Sélectionnez un élément privilégié de ces données (les résultats d'une recherche particulière) et enregistrez-le temporairement en tant que "dataset". (Je voudrais que la taille de l'ensemble de données soit limitée à vraiment grande, disons un demi-million de résultats.)

  3. Effectuez quelques opérations sur cet ensemble de données.

(intégré du frontend dans Rails, bien que je doute que ce soit vraiment pertinent sur la façon de résoudre ce problème particulier.)

La deuxième étape, et comment récupérer les données pour l'étape 3, sont ce qui me donne difficulté. Je dois pouvoir sauvegarder temporairement les ensembles de données, les récupérer quand ils sont nécessaires et les expirer après un certain temps. Le problème est, mes résultats ont des ID de somme de contrôle SHA1, donc chaque ID est de 48 caractères. Un ensemble de données d'enregistrement de 500 000, même si je ne stocke que des ID, représente 22 Mo de données. Je ne peux donc pas avoir une seule table de base de données et y lancer une ligne pour chaque ensemble de données qu'un utilisateur construit.

Est-ce que quelqu'un a déjà eu besoin de quelque chose comme ça avant? Quelle est la meilleure façon d'aborder ce problème? Dois-je générer une table distincte pour chaque ensemble de données qu'un utilisateur construit? Si oui, quel est le meilleur moyen d'expirer/supprimer ces tables après un certain temps? Je peux déployer un serveur MySQL si nécessaire (bien que je n'en ai pas encore un, toutes les données sont dans Solr), et je serais ouvert à un logiciel plus fou si quelque chose d'autre correspond à la facture.

EDIT: Quelques informations plus détaillées, en réponse à Jeff Ferland ci-dessous.

Les objets de données sont immuables, statiques et résident entièrement dans la base de données Solr. Il pourrait être plus efficace en tant que fichiers, mais je préfère (pour des raisons de recherche et de navigation) les garder où ils sont. Ni les données ni les ensembles de données ne doivent être distribués entre plusieurs systèmes, je ne pense pas que nous aurons jamais ce genre de charge. Pour le moment, la foutue chose coule à l'intérieur d'une seule VM (je peux traverser ce pont si j'y arrive). Par «récupérer au besoin», je veux dire quelque chose comme ceci: L'utilisateur exécute une requête de recherche très soigneusement conçue, ce qui leur donne un ensemble d'objets. Ils décident alors qu'ils veulent manipuler cet ensemble. Quand ils (comme un exemple aléatoire) cliquez sur le bouton "graver ces objets par année", je dois être capable de récupérer l'ensemble complet des ID d'objet afin que je puisse les ramener au serveur Solr et exécuter plus de requêtes. Je préfère stocker les ID d'objet (et non la requête de recherche), car le jeu de résultats peut changer sous l'utilisateur lorsque nous ajoutons d'autres objets.

Un "while" correspond approximativement à la durée d'une session utilisateur. Il y a une complication, cependant, qui pourrait avoir de l'importance: je pourrais avoir besoin d'implémenter une file d'attente afin de pouvoir différer le traitement, auquel cas le "while" devrait être "aussi longtemps que nécessaire pour traiter votre travail". Merci à Jeff de m'avoir poussé à fournir le bon type de détail.

Répondre

2

Premier tour: ne représentez pas votre SHA1 comme du texte, mais plutôt comme les 20 octets qu'il prend. La valeur hexadécimale que vous voyez est une façon de montrer des octets sous une forme lisible par l'homme. Si vous les stockez correctement, vous êtes à 9,5 Mo au lieu de 22.Deuxièmement, vous n'avez pas vraiment expliqué la nature de ce que vous êtes en train de faire. Vos ensembles de données sauvegardés sont-ils des références à des objets immuables dans la base de données existante? Que voulez-vous dire en les récupérant en cas de besoin? Combien de temps dure "un moment" quand vous parlez d'expiration? Les données sous-jacentes sont-elles statiques ou dynamiques? Pouvez-vous enregistrer le motif de recherche et un décalage, ou devez-vous enregistrer la référence individuelle?

Les données relatives à une session doivent-elles être insérées dans une base de données? Serait-il plus efficace dans les fichiers? Cela doit-il être réparti entre plusieurs systèmes?

Il reste beaucoup de questions dans ma réponse. Pour cela, vous devez mieux exprimer ou même définir les exigences au-delà de l'aperçu technique que vous avez donné.


Mise à jour: Il existe de nombreuses solutions possibles pour cela. En voici deux:

  • Ecrivez-les dans une seule table (saved_searches ou autre) qui a un identifiant de recherche incrémenté. Points bonus pour l'insertion de vos clés dans l'ordre trié. (search_id unsigned bigint, item_id char (20), clé primaire (search_id, item_id) Cela limitera vraiment la fragmentation, gardera chaque recherche groupée et libèrera les pages dans un ordre à peu près séquentiel. Dans ce cas, vous payez un coût d'insertion et doublez ce coût pour la suppression.Vous devez également parcourir l'ensemble du résultat de la recherche.Il est possible d'itérer le résultat de la recherche dans son intégralité.
  • Si vos éléments de recherche ont un identifiant principal incrémenté de sorte que toute nouvelle insertion dans la base de données aura une valeur plus élevée que tout ce qui est déjà dans la base de données, c'est-à-dire la plus efficace, sinon l'insertion d'un datastamp produirait le même effet avec moins d'efficacité. requête au lieu de seulement les entrées d'index.) Si vous prenez note de cet identifiant maximum, et que vous ne supprimez pas les enregistrements, vous pouvez enregistrer les recherches qui utilisent zéro espace en définissant toujours un ID maximum sur la requête enregistrée.
+0

Question éditée, laissez-moi savoir si l'information supplémentaire aide! –

+0

Réponse éditée - j'espère que ça aide! –

+0

Génial - merci! Je n'avais pas pensé que vous pourriez obtenir un débit décent avec (quelque chose ressemblant) à une table roulante. (La conception de base de données, comme vous pouvez le voir, n'est pas mon fort!) –

Questions connexes