2012-08-03 4 views
1

Je suis en train de réécrire une application qui gère beaucoup de données (environ 100 Go) qui est conçue comme un modèle relationnel.Stockage de données externe énorme non permanent dans l'application C++

L'application est très complexe; C'est une sorte d'outil de conversion pour les données cartographiques ouvertes de grande taille (le monde entier) et il est converti en un fichier de carte pour notre propre logiciel de planification d'itinéraire. L'application convertisseur par exemple contient les nœuds dans la carte des rues ouvertes avec leurs coordonnées et toutes ses balises (beaucoup plus que cela, mais cela devrait servir d'exemple dans cette question).

Situation actuelle:

Parce que ces données est très grande, je le diviser en plusieurs fichiers: Chaque fichier est une carte d'un ID à une valeur atomique (supposons que la liste des balises pour un noeud est une valeur atomique, ce n'est pas le cas mais le stockage de données peut le traiter comme tel). Donc, pour les nœuds, j'ai un fichier contenant les coordonnées du nœud, l'une contenant le nom du nœud et l'autre contenant les balises du nœud, où les nœuds sont identifiés par des identifiants (non continus).

L'application a été divisée en plusieurs applications. Chaque application traite une étape de la conversion. Par conséquent, une telle application doit uniquement gérer certaines des données stockées dans les fichiers. Par exemple, toutes les applications n'ont pas besoin des balises du nœud, mais beaucoup d'entre elles ont besoin des coordonnées du nœud. C'est pourquoi je divise les relations en fichiers, un fichier pour chaque "colonne". Chaque étape de traitement peut lire un fichier entier à la fois dans une structure de données dans la mémoire vive (RAM). Cela garantit que les recherches peuvent être très efficaces (si la structure de données est une carte de hachage).

Je suis en train de réécrire le convertisseur. Il devrait maintenant être une seule application. Et il ne devrait plus utiliser de fichiers séparés pour chaque "colonne". Il devrait plutôt utiliser une architecture bien connue pour tenir des données externes d'une manière relationnelle, comme une base de données, mais beaucoup plus rapidement.

=>Quelle bibliothèque peut fournir les fonctionnalités suivantes?

Exigences:

  • Il doit être très rapide dans itérer sur les données existantes (sans modifier l'ensemble des lignes, mais certaines valeurs dans la ligne actuelle).

  • Il doit fournir une recherche constante ou presque constante, similaire aux cartes de hachage (sans modifier la relation entière).

  • La plupart des types de colonnes sont constamment dimensionnés, mais en général ils ne le sont pas.

  • Il doit être capable d'ajouter de nouvelles lignes à une relation en temps constant ou logarithmique par ligne. La mise à jour en direct d'une sorte d'index de recherche ne sera pas nécessaire. La mise à jour (reconstruction) de l'index peut avoir lieu après la fin d'une étape de traitement complète.

  • Certaines relations reposent sur des valeurs-clés, alors que d'autres sont des matrices (indexées en continu). Les deux devraient fournir des recherches rapides.

  • Cela ne devrait PAS être un processus séparé, comme un SGBD comme MySQL le serait. Le nombre de requêtes sera énorme (environ 10 milliards) et sera totalement le goulot d'étranglement de la performance. Cependant, la mise en cache des requêtes serait une solution possible: Itérer sur une table entière peut être fait dans une seule requête tout en écrivant à une table (à partir de laquelle aucune donnée ne sera lue dans la même étape de traitement). Mais encore: je suppose que les requêtes SQL sérialisant, inter-processus-transmission et désérialisation seront le goulot d'étranglement.

  • Nice-to-have: facile à utiliser. Ce serait très bien si les relations peuvent être utilisées de la même manière que les classes de conteneur standard C++ et Qt.

non exigences (Pourquoi je ne pas besoin d'un SGBD):

  • écriture et la lecture Synchronisation de/vers la même relation. L'application est divisée en plusieurs étapes de traitement; chaque étape a un ensemble de «relations d'entrée» à partir desquelles elle lit et de «relations de sortie» dans lesquelles elle écrit. Cependant, certaines étapes nécessitent de lire certaines colonnes d'une relation tout en écrivant dans d'autres colonnes de la même relation.

  • Relations de jointure. Il y a quelques références croisées entre différentes relations, cependant, elles peuvent être résolues dans mon application si la recherche est assez rapide.

  • Stockage persistant. Une fois la conversion effectuée, toutes les données ne seront plus nécessaires.

  • Les relations basées sur les valeurs-clés ne seront jamais recomposées; les relations basées sur des tableaux ne seront jamais réindexées.

Répondre

0

Je peux penser à plusieurs solutions possibles en fonction de nombreux facteurs que vous n'avez pas quantifiés dans votre question.

Si vous voulez un magasin simple pour rechercher les choses et que vous avez suffisamment de disque, SQLite est très efficace en tant que base de données. Notez qu'il n'y a pas de serveur SQLite, le 'serveur' est lié à votre application.

Personnellement, ce travail ressemble à embarrassingly parallel. Je pense qu'un petit Hadoop cluster ferait un travail rapide de l'ensemble du travail. Vous pouvez le faire tourner en AWS, traiter vos données et les fermer à peu de frais.

+0

Il devrait être intégré dans une application de bureau, donc pas de cloud/cluster/AWS disponible. Une raison pour laquelle je ne voulais pas utiliser SQLite est la sérialisation et la désérialisation des requêtes. – leemes

Questions connexes