Stockage de données chronologiques, relationnelles ou non?
je suis en train de créer un système qui Sonde les appareils pour obtenir des données sur des paramètres variables tels que l'utilisation du CPU, l'utilisation du disque, la température, etc. à intervalles (probablement) de 5 minutes en utilisant SNMP. Le but ultime est de fournir des visualisations à un utilisateur du système sous la forme de graphiques chronologiques.
j'ai étudié L'utilisation de RRDTool dans le passé, mais je l'ai rejeté car stocker indéfiniment les données saisies est important pour mon projet, et je veux un niveau plus élevé et plus souple l'accès aux données capturées. Donc ma question est vraiment:
Ce qui est mieux, un relationnel de la base de données (comme MySQL ou PostgreSQL) ou un non-relationnelles ou de bases de données NoSQL (comme MongoDB ou Redis) en ce qui concerne les performances lors de l'interrogation de données pour la représentation graphique.
relationnel
étant donné une base de données relationnelle, j'utiliserais une table data_instances
, dans laquelle seraient stockées toutes les instances de données capturées pour chaque métrique mesuré pour tous les appareils, avec les champs suivants:
champs: id
fk_to_device
fk_to_metric
metric_value
timestamp
quand je veux dessiner un graphe pour une métrique particulière sur un appareil particulier, je dois interroger cette table singulière filtrage hors les autres appareils, et les autres mesures analysées pour ce dispositif:
SELECT metric_value, timestamp FROM data_instances
WHERE fk_to_device=1 AND fk_to_metric=2
le nombre de lignes ce tableau serait:
d * m_d * f * t
où d
est le nombre de dispositifs , m_d
est le nombre cumulatif nombre de mesures étant enregistré pour tous les dispositifs, f
est le fréquence à laquelle les données sont sollicitées et t
est le montant total de temps le système recueille des données.
pour un utilisateur enregistrement de 10 mesures pour 3 appareils toutes les 5 minutes pendant un an, nous aurions juste sous 5 millions records.
index
sans index sur fk_to_device
et fk_to_metric
scanner cette table en expansion continue prendrait trop de temps. Il est donc nécessaire d'indexer les champs susmentionnés ainsi que timestamp
(pour créer des graphiques avec des périodes localisées).
Non Relationnel (NoSQL)
MongoDB a le concept d'un collection , à la différence des tables, ceux-ci peuvent être créés programmatically sans setup. Avec ceux-ci je pourrais cloisonner le stockage de données pour chaque appareil, ou même chaque métrique enregistrée pour chaque appareil.
Je n'ai aucune expérience avec NoSQL et ne sais pas s'ils fournissent des fonctionnalités d'amélioration des performances de requête telles que l'indexation, cependant le paragraphe précédent propose de faire la plupart de la traditionnelle requête relationnelle fonctionne dans la structure par laquelle les données sont stockées sous NoSQL.
indécis
est-ce qu'une solution relationnelle avec indexation correcte se réduirait à un crawl dans l'année? Ou la structure basée sur la collecte des approches NoSQL (qui correspond à mon modèle mental des données stockées) offre-t-elle un avantage notable?
10 réponses
Définitivement Relationnel. Flexibilité et expansion illimitées.
deux corrections, à la fois en concept et en application, suivies d'une élévation.
Correction
-
Il n'est pas "le filtrage de l'onu, de besoin de données"; il est en sélectionnant uniquement les données nécessaires. Oui, bien sûr, si vous avez un Index pour supporter les colonnes identifiées dans la clause où, il est très rapide, et la requête ne dépend pas de la taille de la table (saisir 1000 lignes d'une table de 16 milliards de lignes est instantané).
-
votre table a un obstacle sérieux. Compte tenu de votre description, le PK réel est (Périphérique, métrique, DateTime). (S'il vous plaît, ne l'appelez pas TimeStamp, cela signifie autre chose, mais c'est un problème mineur.) Le caractère unique de la ligne est identifié par:
(Device, Metric, DateTime)
-
la colonne
Id
ne fait rien, elle est totalement et complètement redondante.- une colonne
Id
n'est jamais une Clé (les lignes dupliquées, qui sont interdites dans une base de données relationnelle, doivent être évitées par d'autres moyens). -
la colonne
Id
nécessite un Index supplémentaire, qui empêche évidemment la vitesse deINSERT/DELETE
, et ajoute à l'espace disque utilisé. -
vous pouvez vous en débarrasser. S'il vous plaît.
- une colonne
-
l'Élévation
-
maintenant que vous avez enlevé l'obstacle, vous ne l'avez peut-être pas reconnu, mais votre tableau est en sixième forme normale. Très grande vitesse, avec un seul Index sur le PK. Pour comprendre, lire cette réponse de la qu'est-Ce que Sixième Forme Normale ? tête de partir.
-
(j'ai un index seulement, et non trois; sur la Non-Sql vous pouvez avoir besoin de trois indices).
-
j'ai exactement la même table (sans la "clé" 151910920, bien sûr). J'ai une colonne supplémentaire
Server
. Je supporte plusieurs clients à distance.(Server, Device, Metric, DateTime)
le tableau peut être utilisé pour faire pivoter les données (c.-à-d.
Devices
à travers le haut etMetrics
sur le côté, ou pivoté) en utilisant exactement le même code SQL (Oui, changer les cellules). J'utilise la table pour ériger une variété illimitée de graphiques et de graphiques pour les clients re leur performance de serveur.-
Moniteur Modèle De Données Statistiques .
(Trop grand pour inline; certains navigateurs ne peuvent pas charger inline; cliquez sur le lien. C'est aussi la version démo obsolète, pour des raisons évidentes, Je ne peux pas vous montrer le produit commercial DM.) -
il me permet de produire des cartes comme celle-ci , six frappes après avoir reçu un fichier de statistiques de surveillance brut du client, en utilisant un simple SELECT commande . Remarquez le mix-and-match; OS et server sur le même graphique; une variété de Pivots. Bien sûr, il n'y a pas de limite au nombre de matrices statistiques, et donc aux graphiques. (Utilisé avec le client aimable autorisation.)
-
les lecteurs qui ne sont pas familiers avec la norme de modélisation des bases de données relationnelles peuvent trouver utile la IDEF1X Notation .
-
Une Chose De Plus
Last but not least, SQL is a IEC/ISO / ANSI Standard. Le freeware est en fait Non-SQL; il est frauduleux d'utiliser le terme SQL s'ils ne fournissent pas le Standard. Ils peuvent fournir des "extras", mais ils sont absents des bases.
a trouvé très intéressantes les réponses ci-dessus. J'essaie d'ajouter quelques considérations.
1) vieillissement des données
le Temps de la série gestion de la nécessité de créer vieillissement politiques. Un scénario typique (par exemple un CPU de serveur de surveillance) nécessite de stocker:
-
1-sec échantillons bruts pendant une courte période (Par exemple pendant 24 heures)
-
5 min détail échantillons globaux pour une moyenne période (par exemple, 1 semaine)
-
1-heure détail sur ce (par exemple jusqu'à 1 an)
bien que les modèles relationnels rendent possible à coup sûr (mon entreprise a mis en œuvre des bases de données centralisées massives pour certains grands clients avec des dizaines de milliers de séries de données) pour la gérer de manière appropriée, la nouvelle race de magasins de données ajouter des fonctionnalités intéressantes à explorer comme:
-
automatisé de données de purge (voir le Redis' EXPIRATION de commande)
-
agrégations multidimensionnelles (par exemple Carte-réduire les emplois a-la-Splunk)
2) collection en temps réel
encore plus important, certains magasins de données non relationnelles sont intrinsèquement distribués et permettent une plus grande efficacité collecte de données en temps réel (ou presque en temps réel) qui pourrait poser un problème avec les SGBDR en raison de la création de points chauds (gestion de l'indexation tout en insérant une table unique). Ce problème dans L'espace RDBMS est généralement résolu en retournant aux procédures d'importation par lots (nous l'avons géré de cette façon dans le passé) alors que les technologies no-sql ont réussi à la collecte massive en temps réel et l'agrégation (voir Splunk par exemple, mentionné dans les réponses précédentes).
votre table a des données dans une seule table. Donc relationnel vs non relationnel n'est pas la question. Fondamentalement, vous devez lire beaucoup de données séquentielles. Maintenant, si vous avez assez de mémoire vive pour stocker des données sur des années, rien de tel que Redis/MongoDB, etc.
la plupart des bases de données NoSQL stockeront vos données au même endroit sur le disque et sous forme compressée pour éviter l'accès à plusieurs disques.
NoSQL fait la même chose que la création de l'index sur le périphérique id et métrique id, mais à sa manière. Avec la base de données même si vous faites ceci l'index et les données peuvent être à des endroits différents et il y aurait beaucoup d'IO de disque.
des outils comme Splunk utilisent NoSQL backends pour stocker des données de séries chronologiques et ensuite utiliser map reduce pour créer des agrégats (ce qui pourrait être ce que vous voulez plus tard). Donc, à mon avis, utiliser NoSQL est une option car les gens l'ont déjà essayé pour des cas d'utilisation similaires. Mais un million de lignes apportera la base de données à crawl (peut-être pas , avec matériel convenable et configurations appropriées).
créer un fichier, le nommer 1_2.données. weired idée? ce que vous obtenez:
- vous économisez jusqu'à 50% d'espace car vous n'avez pas besoin de répéter les valeurs fk_to_device et fk_to_metric pour chaque point de données.
- vous économisez encore plus d'espace car vous n'avez pas besoin d'indices.
- Sauvegardez les paires de (timestamp, metric_value) dans le fichier en ajoutant les données pour obtenir une commande par timestamp gratuitement. (en supposant que vos sources ne pas envoyer de données de commande pour un appareil)
= > les requêtes par timestamp tournent étonnamment vite parce que vous pouvez utiliser la recherche binaire pour trouver le bon endroit dans le fichier à lire.
si vous aimez encore plus optimisé commencer à penser à diviser vos fichiers comme cela;
- 1_2_januar2014.données
- 1_2_february2014.données
- 1_2_march2014.données
ou utilisez kdb+ de http://kx.com parce qu'ils font tout cela pour vous:) orienté colonne est ce qui peut vous aider.
il y a une solution basée sur le nuage et orientée sur la colonne qui apparaît, alors vous pouvez jeter un oeil à: http://timeseries.guru
c'est un problème que nous avons eu à résoudre à ApiAxle. Nous a écrit un billet de blog sur la façon dont nous l'avons fait en utilisant Redis. Il n'est pas sorti depuis très longtemps, mais il s'avère efficace.
j'ai également utilisé RRDTool pour un autre projet qui était excellent.
je pense que la réponse à ce genre de question devrait porter principalement sur la façon dont votre base de données utilise le stockage. Certains serveurs de bases de données utilisent la RAM et le disque, certains utilisent la RAM seulement (disque optionnel pour la persistance), etc. La plupart des solutions de base de données SQL courantes utilisent la mémoire + le stockage de disque et écrit les données dans une disposition basée de ligne (chaque raw insérée est écrite dans le même emplacement physique). Pour les magasins de séries chronologiques, dans la plupart des cas la charge de travail est quelque chose comme: quantité massive de renforts, tandis que les lectures sont de la colonne de base (dans la plupart des cas, vous voulez lire un éventail de données à partir d'une colonne spécifique, ce qui représente une métrique)
j'ai trouvé bases de données Columnar (google it, vous trouverez MonetDB, InfoBright, parAccel, etc) font un travail formidable pour les séries chronologiques.
quant à votre question, qui personnellement je pense est quelque peu invalide (comme toutes les discussions utilisant le terme de faute NoSQL-IMO): Vous pouvez utiliser un serveur de Base de données peut parler SQL sur une main, ce qui rend votre vie très facile car tout le monde connaît SQL depuis de nombreuses années et ce langage a été perfectionné encore et encore pour les requêtes de données; mais toujours utiliser RAM, CPU Cache et le disque D'une manière orientée Columnar, ce qui rend votre solution mieux adapté série temporelle
5 Millions de lignes n'est rien pour les données torrentielles d'aujourd'hui. Les données devraient être dans le TB ou le PB dans quelques mois. À ce stade, les SGBDR ne sont pas adaptés à la tâche et nous avons besoin de l'évolutivité linéaire des bases de données NoSql. Les performances seraient atteintes pour la partition colonnaire utilisée pour stocker les données, ajoutant plus de colonnes et moins de lignes de sorte de concept pour augmenter les performances. Tirer parti du travail TSDB ouvert effectué sur HBASE ou MapR_DB, etc.
je fais face à des exigences similaires régulièrement, et ont récemment commencé à utiliser Zabbix pour recueillir et stocker ce type de données. Zabbix a sa propre capacité de graphage, mais il est assez facile d'extraire les données de la base de données de Zabbix et de les traiter comme vous le souhaitez. Si vous N'avez pas déjà vérifié Zabbix, vous pourriez trouver le temps de le faire.
Vous devriez regarder dans le Temps de la série de la base de données . Il a été créé à cette fin.
une base de données de séries chronologiques (TSDB) est un système logiciel qui est optimisé pour le traitement des données de séries chronologiques, tableaux de nombres indexés par temps (un datetime ou un intervalle de datetime).
exemple Populaire de base de données de séries chronologiques InfluxDB