2014-06-12 8 views
2

J'ai quelques données de mesure scientifiques qui devraient être stockées de manière permanente dans un magasin de données quelconque.Stockage de données pour les données de séries chronologiques

Je cherche un moyen de stocker des mesures à partir de 100 000 capteurs avec des données de mesure accumulées sur plusieurs années jusqu'à environ 1 000 000 de mesures par capteur. Chaque capteur produit une lecture une fois par minute ou moins fréquemment. Ainsi, le flux de données n'est pas très important (environ 200 mesures par seconde dans le système complet). Les capteurs ne sont pas synchronisés.

Les données elles-mêmes sont des flux de triplets: [horodatage] [numéro de capteur] [valeur], où tout peut être représenté comme une valeur de 32 bits.

Dans la forme la plus simple, ce flux serait stocké tel quel dans une seule table à trois colonnes. Ensuite, la requête serait:

SELECT timestamp,value 
    FROM Data 
    WHERE sensor=12345 AND timestamp BETWEEN '2013-04-15' AND '2013-05-12' 
    ORDER BY timestamp 

Malheureusement, DBMS basés sur des lignes cela donne une très mauvaise performance, comme la masse de données est grande, et les données que nous voulons est dispersée de façon presque égale en elle. (Essayer de sélectionner quelques centaines de milliers d'enregistrements à partir de milliards d'enregistrements.) Ce dont j'ai besoin est un temps de réponse raisonnable pour la consommation humaine (les données seront représentées graphiquement pour un utilisateur), c'est-à-dire quelques secondes plus le transfert de données.

Une autre approche consisterait à stocker les données d'un capteur dans une table. Ensuite, la requête deviendrait:

SELECT timestamp,value 
    FROM Data12345 
    WHERE timestamp BETWEEN '2013-04-15' AND '2013-05-12' 
    ORDER BY timestamp 

Cela donnerait une bonne performance de lecture, le résultat serait un certain nombre de lignes consécutives d'une table relativement faible (généralement moins d'un million de lignes). Cependant, le SGBDR doit contenir 100 000 tables qui sont utilisées en quelques minutes seulement. Cela ne semble pas possible avec les systèmes communs. D'autre part, le SGBDR ne semble pas être le bon outil, car il n'y a pas de relations dans les données.

Je suis en mesure de démontrer qu'un seul serveur peut faire face à la charge en utilisant le système de mickeymouse suivant:

  1. Chaque capteur a son propre fichier dans le système de fichiers.
  2. Lorsqu'une donnée arrive, son fichier est ouvert, les données sont ajoutées et le fichier est fermé.
  3. Les requêtes ouvrent le fichier respectif, trouvent les points de début et de fin des données et lisent toutes les données intermédiaires.

Très peu de lignes de code. Les performances dépendent du système (type de stockage, système de fichiers, système d'exploitation), mais il ne semble pas y avoir de gros obstacles. Cependant, si j'abandonne cette voie, je finis par écrire mon propre code pour le partitionnement, la sauvegarde, le déplacement des données plus anciennes dans le stockage (cloud), etc. Ensuite, cela ressemble à mon propre SGBD, qui sonne comme réinventer la roue (encore).

Existe-t-il un moyen standard de stocker le type de données dont je dispose? Un astucieux astuce NoSQL?

+0

Oui, ce n'est pas vraiment une question SO, mais c'est intéressant. Consultez tous les autres sites sur http://stackexchange.com/sites, tels que peut-être "Programmeurs" ou "Informatique". Je dirais que ce que tu veux est très performant. Vous pouvez le faire avec un système "vanilla" comme SQL Server ou Oracle. Mais vos objectifs de vitesse sont difficiles. 1 milliard de lignes sortis en 3 secondes == puissance de traitement massive et matériel de fantaisie et parallélisme logique. Les systèmes de nuages ​​seront également trop lent sur le fil. Si vous pouvez abandonner une certaine vitesse, ce n'est pas si difficile puisque la structure de données simple vous aide, comme vous le savez déjà. –

+1

J'ai essayé de paraphraser la question pour décrire le problème plus clairement. La bande passante de sortie n'est pas un problème, car j'ai seulement besoin d'obtenir une quantité modérée de données d'un capteur à la fois. Les requêtes typiques retourneraient peut-être 20 000 points de données. Aucun matériel sophistiqué n'est nécessaire - au moins les benchmarks préliminaires suggèrent que cela peut être fait avec un seul serveur. – DrV

+0

Nice. Dans ce cas, votre implémentation est probablement plus importante que le système. L'architecture des données est toujours la clé :). S'amuser! –

Répondre

1

Semble vraiment un problème assez facile. 100 milliards d'enregistrements, 12 octets par enregistrement -> 1,2 To ce n'est même pas un gros volume pour les disques durs modernes. En LMDB, j'utiliserais une sous-DB par capteur. Ensuite, votre clé/valeur est juste un horodatage 32 bits/lecture de capteur 32 bits, et toutes vos récupérations de données seront de simples balayages de plage sur la clé.Vous pouvez facilement récupérer de l'ordre de 50M enregistrements/sec avec LMDB. (Voir les gars de SkyDB faisant juste cela https://groups.google.com/forum/#!msg/skydb/CMKQSLf2WAw/zBO1X35alxcJ)

+0

Merci pour votre opinion d'expert! J'aime la façon dont le LMDB est fait, et j'ai pensé à l'utiliser dans cette application, mais je n'ai pas pensé à utiliser des subDB. J'admets mon ignorance à leur égard et je dois demander s'il y a une différence dans l'utilisation, disons, de 500 bases de données avec 200 sous-DB chacune ou de 1 base de données et de 100 000 sous-bases de données. (Les 50 000 000 enregistrements/s sont vraiment impressionnants, mais malheureusement mes données vont être sur un disque, donc mon inquiétude est le nombre de pages aléatoires lues ou écrites.) – DrV

+1

LMDB est une conception d'un seul auteur, donc vous le feriez envisager de diviser en 500 bases de données afin de soutenir 500 écrivains simultanés. En dehors de cela, il y a une question de savoir combien de sous-DB doivent être ouverts simultanément - l'initial mdb_dbi_open() fait une recherche linéaire dans la table des DBI ouverts, donc il peut être lent pour 100.000. (Mais cela ne peut pas non plus avoir d'importance, puisque l'ouverture ne doit être effectuée qu'une fois par course.) À part cela, il n'y a pas de réelle différence de performance. – hyc

+1

InfluxDB est une base de données de séries chronologiques qui peut utiliser LMDB http://influxdb.com/blog/2014/06/20/leveldb_vs_hyperleveldb_vs_lmdb_performance.html L'utilisation de la fonction Duplicates triés du LMDB peut également vous faire économiser de l'espace et du temps, voir mes commentaires sur leur poste. – hyc

Questions connexes