Modélisation des données - Amazon Timestream

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Modélisation des données

Amazon Timestream LiveAnalytics for est conçu pour collecter, stocker et analyser des séries chronologiques provenant d'applications et d'appareils émettant une séquence de données horodatée. Pour des performances optimales, les données envoyées à Timestream LiveAnalytics doivent avoir des caractéristiques temporelles et le temps doit être une composante essentielle des données.

Timestream for vous LiveAnalytics offre la flexibilité de modéliser vos données de différentes manières en fonction des exigences de votre application. Dans cette section, nous abordons plusieurs de ces modèles et vous donnons des directives pour optimiser vos coûts et vos performances. Familiarisez-vous avec Timestream pour des LiveAnalytics concepts tels que les dimensions et les mesures. Dans cette section, vous en apprendrez davantage sur :

Lorsque vous décidez de créer une seule table ou plusieurs tables pour stocker les données, tenez compte des points suivants :

  • Quelles données placer dans la même table ou lorsque vous souhaitez séparer les données entre plusieurs tables et bases de données.

  • Comment choisir entre Timestream pour les enregistrements à LiveAnalytics mesures multiples ou les enregistrements à mesure unique, et les avantages de la modélisation à l'aide d'enregistrements à mesures multiples, en particulier lorsque votre application suit plusieurs mesures en même temps instantanément.

  • Quels attributs modéliser sous forme de dimensions ou de mesures.

  • Comment utiliser efficacement les attributs des noms de mesures pour optimiser la latence de vos requêtes.

Table unique ou tables multiples

Lorsque vous modélisez vos données dans une application, un autre aspect important est de savoir comment les modéliser dans des tables et des bases de données. Les bases de données et les tables de Timestream for LiveAnalytics sont des abstractions destinées au contrôle d'accès, à la spécification des KMS clés, aux périodes de conservation, etc. Timestream permet de partitionner LiveAnalytics automatiquement vos données et est conçu pour adapter les ressources en fonction de l'ingestion, du stockage, de la charge des requêtes et des exigences de vos applications.

Dans Timestream for, un tableau LiveAnalytics peut prendre en charge des pétaoctets de données stockées, des dizaines de gigaoctets par seconde d'écriture de données, et les requêtes peuvent en traiter des centaines par heure. TBs Les requêtes de Timestream for LiveAnalytics peuvent couvrir plusieurs tables et bases de données, fournissant des jointures et des unions pour fournir un accès fluide à vos données sur plusieurs tables et bases de données. L'échelle des données ou le volume de demandes ne sont donc généralement pas la principale préoccupation lorsque vous décidez comment organiser vos données dans Timestream for. LiveAnalytics Vous trouverez ci-dessous quelques points importants à prendre en compte lors du choix des données à colocaliser dans la même table par rapport à des tables différentes ou à des tables de différentes bases de données.

  • Les politiques de conservation des données (conservation de la mémoire, conservation de la mémoire magnétique, etc.) sont prises en charge au niveau de la granularité d'une table. Par conséquent, les données qui nécessitent des politiques de conservation différentes doivent figurer dans des tables différentes.

  • AWS KMS les clés utilisées pour chiffrer vos données sont configurées au niveau de la base de données. Par conséquent, les différentes exigences en matière de clés de chiffrement impliquent que les données devront se trouver dans différentes bases de données.

  • Timestream for LiveAnalytics prend en charge le contrôle d'accès basé sur les ressources au niveau de la granularité des tables et des bases de données. Tenez compte de vos exigences en matière de contrôle d'accès lorsque vous décidez quelles données vous souhaitez écrire dans la même table ou dans des tables différentes.

  • Tenez compte des limites relatives au nombre de dimensions, de noms de mesures et de noms d'attributs à mesures multiples lorsque vous décidez quelles données sont stockées dans quelle table.

  • Tenez compte de la charge de travail de vos requêtes et de vos modèles d'accès lorsque vous décidez de la manière dont vous organisez vos données, car la latence des requêtes et la facilité de rédaction de vos requêtes en dépendront.

    • Si vous stockez les données que vous demandez fréquemment dans la même table, cela facilitera généralement la rédaction de vos requêtes, ce qui vous évitera d'avoir à écrire des jointures, des unions ou des expressions de table communes. Cela se traduit également généralement par une réduction de la latence des requêtes. Vous pouvez utiliser des prédicats sur les dimensions et les noms de mesures pour filtrer les données pertinentes pour les requêtes.

      Par exemple, imaginez le cas où vous stockez des données provenant d'appareils situés sur six continents. Si vos requêtes accèdent fréquemment à des données provenant de plusieurs continents pour obtenir une vue globale agrégée, le stockage des données de ces continents dans la même table facilitera la rédaction des requêtes. D'autre part, si vous stockez des données sur différentes tables, vous pouvez toujours combiner les données dans la même requête, mais vous devrez écrire une requête pour unir les données des différentes tables.

    • Timestream for LiveAnalytics utilise le partitionnement et l'indexation adaptatifs de vos données. Les requêtes ne sont donc facturées que pour les données pertinentes à vos requêtes. Par exemple, si vous avez une table stockant les données d'un million d'appareils sur six continents, si votre requête contient des prédicats du type « WHERE device_id = 'abcdef' ou »WHERE continent = 'North America', les requêtes ne sont facturées que pour les données relatives à l'appareil ou au continent.

    • Dans la mesure du possible, si vous utilisez le nom de la mesure pour séparer les données d'une même table qui ne sont pas émises en même temps ou qui ne sont pas fréquemment demandées, WHERE measure_name = 'cpu' en utilisant des prédicats tels que ceux de votre requête, vous bénéficiez non seulement des avantages de la mesure, mais Timestream for LiveAnalytics peut également éliminer efficacement les partitions dont le nom de mesure n'est pas utilisé dans votre prédicat de requête. Cela vous permet de stocker des données associées avec différents noms de mesures dans la même table sans impact sur la latence ou les coûts des requêtes, et évite de répartir les données dans plusieurs tables. Le nom de la mesure est essentiellement utilisé pour partitionner les données et supprimer les partitions non pertinentes pour la requête.

Enregistrements à mesures multiples contre enregistrements à mesure unique

Timestream for vous LiveAnalytics permet d'écrire des données avec plusieurs mesures par enregistrement (mesures multiples) ou une seule mesure par enregistrement (mesure unique).

Enregistrements à mesures multiples

Dans de nombreux cas d'utilisation, un appareil ou une application que vous suivez peut émettre plusieurs mesures ou événements au même horodatage. Dans de tels cas, vous pouvez stocker toutes les métriques émises au même horodatage dans le même enregistrement multi-mesures. C'est-à-dire que toutes les mesures stockées dans le même enregistrement multi-mesures apparaissent sous forme de colonnes différentes dans la même ligne de données.

Supposons, par exemple, que votre application émet des métriques telles que cpu, memory, disk_iops à partir d'un périphérique mesuré au même moment. Voici un exemple d'une telle table où plusieurs métriques émises simultanément sont stockées dans la même ligne. Vous verrez alors deux hôtes émettre les métriques une fois par seconde.

Hostname nom_mesure Heure cpu Mémoire disk_iops
Hôte-24GJU metrics 2021-12-01 19:00:00 35 54,9 38,2
Hôte-24GJU metrics 2021-12-01 19:00:01 36 58 39
Hôte - 28 GJU metrics 2021-12-01 19:00:00 15 55 92
Hôte - 28 GJU metrics 2021-12-01 19:00:01 16 50 40

Enregistrements à mesure unique

Les enregistrements de mesures uniques conviennent lorsque vos appareils émettent des mesures différentes à différentes périodes, ou lorsque vous utilisez une logique de traitement personnalisée qui émet metrics/events at different time periods (for instance, when a device's reading/state des modifications). Comme chaque mesure possède un horodatage unique, les mesures peuvent être stockées dans leurs propres enregistrements dans Timestream for. LiveAnalytics Prenons l'exemple d'un capteur IoT, qui suit la température et l'humidité du sol, qui émet un enregistrement uniquement lorsqu'il détecte un changement par rapport à l'entrée signalée précédemment. L'exemple suivant fournit un exemple de telles données émises à l'aide d'enregistrements de mesures uniques.

device_id nom_mesure Heure valeur_mesure : double value_mesure : :bigint
sensor-sea478 temperature 2021-12-01 19:22:32 35 NULL
sensor-sea478 temperature 2021-12-01 18:07:51 36 NULL
sensor-sea478 humidité 2021-12-01 19:05:30 NULL 21
sensor-sea478 humidité 2021-12-01 19:00:01 NULL 23

Comparaison des enregistrements à mesure unique et à mesures multiples

Timestream for vous LiveAnalytics offre la flexibilité de modéliser vos données sous forme d'enregistrements à mesure unique ou à mesures multiples en fonction des exigences et des caractéristiques de votre application. Une seule table peut stocker à la fois des enregistrements de mesures uniques et de plusieurs mesures, si les exigences de votre application le souhaitent. En général, lorsque votre application émet plusieurs mesures/événements simultanément, il est généralement recommandé de modéliser les données sous forme d'enregistrements multi-mesures pour un accès performant aux données et un stockage rentable des données.

Par exemple, si vous considérez un cas d'DevOps utilisation pour suivre les métriques et les événements provenant de centaines de milliers de serveurs, chaque serveur émet périodiquement 20 métriques et 5 événements, les événements et les métriques étant émis en même temps instantanément. Ces données peuvent être modélisées à l'aide d'enregistrements à mesures uniques ou à l'aide d'enregistrements à mesures multiples (voir le générateur de données open source pour le schéma obtenu). Dans ce cas d'utilisation, la modélisation des données à l'aide d'enregistrements à mesures multiples par rapport à des enregistrements à mesures uniques donne les résultats suivants :

  • Mesure de l'ingestion - Les enregistrements à mesures multiples permettent de réduire d'environ 40 % le nombre d'octets d'ingestion écrits.

  • Traitement par lots d'ingestion - Les enregistrements à mesures multiples entraînent l'envoi de lots de données plus importants, ce qui signifie que les clients ont besoin de moins de threads et de moins de threads CPU pour traiter l'ingestion.

  • Mesure du stockage - Les enregistrements à mesures multiples réduisent d'environ 8 fois la capacité de stockage, ce qui se traduit par des économies de stockage importantes à la fois en termes de mémoire et de stockage magnétique.

  • Latence des requêtes : les enregistrements à mesures multiples réduisent la latence des requêtes pour la plupart des types de requêtes par rapport aux enregistrements à mesure unique.

  • Nombre d'octets mesurés par requête : pour les requêtes analysant moins de 10 Mo de données, les enregistrements à mesure unique et à mesures multiples sont comparables. Pour les requêtes accédant à une seule mesure et scannant des données de plus de 10 Mo, les enregistrements d'une seule mesure se traduisent généralement par une réduction du nombre d'octets mesurés. Pour les requêtes faisant référence à 3 mesures ou plus, les enregistrements à mesures multiples se traduisent par une réduction du nombre d'octets mesurés.

  • Facilité d'expression de requêtes à mesures multiples : lorsque vos requêtes font référence à plusieurs mesures, la modélisation de vos données à l'aide d'enregistrements à mesures multiples permet d'écrire des requêtes plus simples et plus compactes.

Les facteurs précédents varieront en fonction du nombre de mesures que vous suivez, du nombre de dimensions de vos données, etc. Bien que l'exemple précédent fournisse des données concrètes, nous constatons que dans de nombreux scénarios d'application et cas d'utilisation, si votre application émet plusieurs mesures au même instant, le stockage des données sous forme d'enregistrements de mesures multiples est plus efficace. De plus, les enregistrements à mesures multiples vous offrent la flexibilité des types de données et le stockage de plusieurs autres valeurs en tant que contexte (par exemple, le stockage de la demande IDs et des horodatages supplémentaires, dont il sera question plus loin).

Notez qu'un enregistrement multi-mesures peut également modéliser des mesures éparses, comme dans l'exemple précédent pour les enregistrements de mesures uniques : vous pouvez utiliser le nom de la mesure pour stocker le nom de la mesure et utiliser un nom d'attribut multi-mesures générique, tel que value_double pour stocker les mesures, value_bigint pour stocker les DOUBLE mesures, value_timestamp pour stocker des valeurs supplémentaires, etc. BIGINT TIMESTAMP

Dimensions et mesures

Un tableau dans Timestream vous LiveAnalytics permet de stocker des dimensions (identifiant les attributs de l'appareil/des données que vous stockez) et des mesures (les mesures/valeurs que vous suivez). Consultez Timestream pour les concepts pour plus de détails. LiveAnalytics Lorsque vous modélisez votre application sur Timestream pour LiveAnalytics, la façon dont vous mappez vos données en dimensions et en mesures a un impact sur votre ingestion et la latence des requêtes. Vous trouverez ci-dessous des directives sur la manière de modéliser vos données sous forme de dimensions et de mesures que vous pouvez appliquer à votre cas d'utilisation.

Choix des dimensions

Les données qui identifient la source qui envoie les données de série chronologique s'adaptent naturellement aux dimensions, qui sont des attributs qui ne changent pas au fil du temps. Par exemple, si un serveur émet des métriques, les attributs identifiant le serveur, tels que le nom d'hôte, la région, le rack, la zone de disponibilité, sont candidats aux dimensions. De même, pour un appareil IoT doté de plusieurs capteurs signalant des données chronologiques, l'identifiant de l'appareil, l'identifiant du capteur, etc. sont candidats pour les dimensions.

Si vous écrivez des données sous forme d'enregistrements à mesures multiples, les dimensions et les attributs à mesures multiples apparaissent sous forme de colonnes dans le tableau lorsque vous effectuez DESCRIBE ou exécutez une SELECT instruction sur le tableau. Ainsi, lorsque vous rédigez vos requêtes, vous pouvez librement utiliser les dimensions et les mesures de la même requête. Toutefois, lorsque vous créez votre enregistrement d'écriture pour ingérer des données, gardez à l'esprit les points suivants lorsque vous choisissez les attributs spécifiés sous forme de dimensions et ceux qui sont des valeurs de mesure :

  • Les noms des dimensions, les valeurs, le nom des mesures et l'horodatage identifient de manière unique les données des séries chronologiques. Timestream for LiveAnalytics utilise cet identifiant unique pour dédupliquer automatiquement les données. En d'autres termes, si Timestream pour LiveAnalytics reçoit deux points de données portant les mêmes valeurs de nom de dimension, de valeurs de dimension, de nom de mesure et d'horodatage, si les valeurs ont le même numéro de version, alors Timestream pour les dédoublons. LiveAnalytics Si la nouvelle demande d'écriture possède une version inférieure aux données déjà existantes dans Timestream pour LiveAnalytics, la demande d'écriture est rejetée. Si la nouvelle demande d'écriture possède une version supérieure, la nouvelle valeur remplace l'ancienne valeur. Par conséquent, la façon dont vous choisissez vos valeurs de dimension aura un impact sur ce comportement de déduplication.

  • Les noms et valeurs des dimensions ne peuvent pas être mis à jour, la valeur de mesure peut l'être. Ainsi, toutes les données susceptibles de nécessiter des mises à jour sont mieux modélisées sous forme de valeurs de mesure. Par exemple, si vous avez une machine dans l'usine dont la couleur peut changer, vous pouvez modéliser la couleur sous forme de valeur de mesure, sauf si vous souhaitez également utiliser la couleur comme attribut d'identification nécessaire à la déduplication. En d'autres termes, les valeurs de mesure peuvent être utilisées pour stocker des attributs qui ne changent que lentement au fil du temps.

Notez qu'un tableau dans Timestream pour LiveAnalytics ne limite pas le nombre de combinaisons uniques de noms et de valeurs de dimension. Par exemple, des milliards de combinaisons de valeurs uniques de ce type peuvent être stockées dans une table. Cependant, comme vous le verrez dans les exemples suivants, un choix judicieux des dimensions et des mesures peut optimiser considérablement la latence de vos demandes, en particulier pour les requêtes.

Dimensions uniques IDs

Si le scénario de votre application nécessite que vous stockiez un identifiant unique pour chaque point de données (par exemple, un identifiant de demande, un identifiant de transaction ou un identifiant de corrélation), la modélisation de l'attribut ID en tant que valeur de mesure améliorera considérablement la latence des requêtes. Lorsque vous modélisez vos données à l'aide d'enregistrements à mesures multiples, l'ID apparaît sur la même ligne en contexte avec vos autres dimensions et données de séries chronologiques, afin que vos requêtes puissent continuer à les utiliser efficacement. Par exemple, si l'on considère un cas d'DevOps utilisation où chaque point de données émis par un serveur possède un attribut d'ID de demande unique, la modélisation de l'ID de demande sous forme de valeur de mesure permet de réduire la latence des requêtes jusqu'à 4 fois plus faible pour différents types de requêtes, par opposition à la modélisation de l'ID de demande unique en tant que dimension.

Vous pouvez utiliser la même analogie pour des attributs qui ne sont pas totalement uniques pour chaque point de données, mais qui comportent des centaines de milliers ou des millions de valeurs uniques. Vous pouvez modéliser ces attributs sous forme de dimensions ou de valeurs de mesure. Vous souhaiterez le modéliser sous forme de dimension si les valeurs sont nécessaires à la déduplication sur le chemin d'écriture, comme indiqué précédemment, ou si vous l'utilisez souvent comme prédicat (par exemple, dans la WHERE clause avec un prédicat d'égalité sur une valeur de cet attribut, telle que l'device_id = ‘abcde’endroit où votre application suit des millions d'appareils) dans vos requêtes.

Richesse des types de données avec des enregistrements à mesures multiples

Les enregistrements à mesures multiples vous offrent la flexibilité nécessaire pour modéliser efficacement vos données. Les données que vous stockez dans un enregistrement multi-mesures apparaissent sous forme de colonnes dans le tableau, à l'instar des dimensions, ce qui permet de demander des dimensions et des valeurs de mesure avec la même facilité. Vous avez observé certains de ces modèles dans les exemples présentés précédemment. Vous trouverez ci-dessous des modèles supplémentaires permettant d'utiliser efficacement les enregistrements à mesures multiples afin de répondre aux cas d'utilisation de votre application.

Les enregistrements à mesures multiples prennent en charge les attributs des types de données DOUBLEBIGINT,VARCHAR,BOOLEAN, etTIMESTAMP. Par conséquent, ils correspondent naturellement à différents types d'attributs :

  • Informations de localisation : par exemple, si vous souhaitez suivre l'emplacement (exprimé sous forme de latitude et de longitude), le modéliser sous la forme d'un attribut à mesures multiples réduira le temps de latence des requêtes par rapport au stockage sous forme de VARCHAR dimensions, en particulier lorsque vous avez des prédicats sur la latitude et les longitudes.

  • Plusieurs horodatages dans un enregistrement : si le scénario de votre application vous oblige à suivre plusieurs horodatages pour un enregistrement de série chronologique, vous pouvez les modéliser sous forme d'attributs supplémentaires dans l'enregistrement multi-mesures. Ce modèle peut être utilisé pour stocker des données avec des horodatages futurs ou passés. Notez que chaque enregistrement utilisera toujours l'horodatage dans la colonne de temps pour partitionner, indexer et identifier un enregistrement de manière unique.

En particulier, si vous avez des données numériques ou des horodatages sur lesquels vous avez des prédicats dans la requête, la modélisation de ces attributs sous forme d'attributs à mesures multiples, par opposition à des dimensions, réduira le temps de latence des requêtes. En effet, lorsque vous modélisez de telles données à l'aide des types de données riches pris en charge dans les enregistrements à mesures multiples, vous pouvez exprimer les prédicats à l'aide de types de données natifs au lieu de convertir des valeurs en un autre type de VARCHAR données si vous avez modélisé ces données sous forme de dimensions.

Utilisation du nom de la mesure avec des enregistrements de plusieurs mesures

Les tables de Timestream prennent en LiveAnalytics charge un attribut spécial (ou une colonne) appelé nom de mesure. Vous spécifiez une valeur pour cet attribut pour chaque enregistrement pour lequel vous écrivez dans Timestream. LiveAnalytics Pour les enregistrements d'une seule mesure, il est naturel d'utiliser le nom de votre métrique (tel que cpu, mémoire pour les métriques du serveur, ou température, pression pour les métriques du capteur). Lorsque vous utilisez des enregistrements multi-mesures, étant donné que les attributs d'un enregistrement multi-mesures sont nommés (et ces noms deviennent des noms de colonnes dans la table), cpu, mémoire ou température, la pression peut devenir des noms d'attributs multi-mesures. Il est donc naturel de se demander comment utiliser efficacement le nom de la mesure.

Timestream for LiveAnalytics utilise les valeurs de l'attribut du nom de la mesure pour partitionner et indexer les données. Par conséquent, si une table possède plusieurs noms de mesures différents et si les requêtes utilisent ces valeurs comme prédicats de requête, Timestream for LiveAnalytics peut utiliser son partitionnement et son indexation personnalisés pour éliminer les données qui ne sont pas pertinentes pour les requêtes. Par exemple, si votre table contient des noms de mesures de processeur et de mémoire, et que votre requête contient un prédicatWHERE measure_name = 'cpu', Timestream for LiveAnalytics peut efficacement affiner les données pour les noms de mesures non pertinents pour la requête, par exemple les lignes contenant une mémoire de nom de mesure dans cet exemple. Cet élagage s'applique même lorsque vous utilisez des noms de mesures avec des enregistrements de plusieurs mesures. Vous pouvez utiliser efficacement l'attribut de nom de mesure comme attribut de partitionnement pour une table. Le nom de la mesure ainsi que les noms et valeurs des dimensions, ainsi que le temps, sont utilisés pour partitionner les données dans un flux temporel pour LiveAnalytics une table. Tenez compte des limites du nombre de noms de mesures uniques autorisés dans un flux temporel pour LiveAnalytics une table. Notez également qu'un nom de mesure est également associé à un type de données de valeur de mesure. Par exemple, un seul nom de mesure ne peut être associé qu'à un seul type de valeur de mesure. Ce type peut être l'un des DOUBLE suivants : BIGINTBOOLEAN,VARCHAR, etMULTI. Les enregistrements de plusieurs mesures stockés avec un nom de mesure auront le type de données comme MULTI suit. Étant donné qu'un seul enregistrement multi-mesures peut stocker plusieurs métriques avec différents types de données (DOUBLE,BIGINT, VARCHARBOOLEAN, etTIMESTAMP), vous pouvez associer des données de différents types dans un enregistrement multi-mesures.

Les sections suivantes décrivent quelques exemples de la manière dont l'attribut de nom de mesure peut être utilisé efficacement pour regrouper différents types de données dans la même table.

Les capteurs IoT signalent la qualité et la valeur

Supposons que vous disposiez d'une application surveillant les données provenant de capteurs IoT. Chaque capteur suit différentes mesures, telles que la température et la pression. Outre les valeurs réelles, les capteurs signalent également la qualité des mesures, qui est une mesure de la précision de la lecture et une unité de mesure. Comme la qualité, l'unité et la valeur sont émises ensemble, elles peuvent être modélisées sous forme d'enregistrements à mesures multiples, comme le montre l'exemple de données ci-dessous où device_id est une dimension, la qualité, la valeur et l'unité sont des attributs à mesures multiples :

device_id nom_mesure Heure Qualité Valeur Unité
sensor-sea478 temperature 2021-12-01 19:22:32 92 35 c
sensor-sea478 temperature 2021-12-01 18:07:51 93 34 c
sensor-sea478 pressure (pression) 2021-12-01 19:05:30 98 31 psi
sensor-sea478 pressure (pression) 2021-12-01 19:00:01 24 132 psi

Cette approche vous permet de combiner les avantages des enregistrements multi-mesures avec le partitionnement et l'élagage des données en utilisant les valeurs du nom de la mesure. Si les requêtes font référence à une seule mesure, par exemple la température, vous pouvez inclure un prédicat de nom de mesure dans la requête. Voici un exemple d'une telle requête, qui projette également l'unité pour les mesures dont la qualité est supérieure à 90.

SELECT device_id, time, value AS temperature, unit FROM db.table WHERE time > ago(1h) AND measure_name = 'temperature' AND quality > 90

L'utilisation du prédicat measure_name sur la requête permet LiveAnalytics à Timestream de supprimer efficacement les partitions et les données qui ne sont pas pertinentes pour la requête, améliorant ainsi la latence de votre requête.

Il est également possible de stocker toutes les métriques dans le même enregistrement multi-mesures si toutes les métriques sont émises au même horodatage et/ou si plusieurs métriques sont interrogées ensemble dans la même requête. Par exemple, vous pouvez créer un enregistrement multi-mesures avec les attributs temperature_quality, temperature_value, temperature_unit, pressure_quality, pressure_value, pressure_unit, etc. La plupart des points abordés précédemment concernant la modélisation des données à l'aide d'enregistrements à mesures uniques ou à mesures multiples s'appliquent à votre décision quant à la manière de modéliser les données. Tenez compte de vos modèles d'accès aux requêtes et de la manière dont vos données sont générées pour choisir un modèle qui optimise les coûts, l'ingestion et la latence des requêtes, ainsi que la facilité de rédaction de vos requêtes.

Différents types de métriques dans le même tableau

Un autre cas d'utilisation dans lequel vous pouvez combiner des enregistrements de plusieurs mesures avec des valeurs de nom de mesure consiste à modéliser différents types de données émis indépendamment par le même appareil. Prenons le cas d'utilisation de la DevOps surveillance : les serveurs émettent deux types de données : des métriques émises régulièrement et des événements irréguliers. Le schéma décrit dans le générateur de données modélisant un cas d' DevOps utilisation est un exemple de cette approche. Dans ce cas, vous pouvez stocker les différents types de données émises par le même serveur dans la même table en utilisant différents noms de mesures. Par exemple, toutes les métriques émises en même temps sont stockées avec les métriques de nom de mesure. Tous les événements émis à un instant différent de celui des métriques sont stockés avec les événements de nom de mesure. Le schéma de mesure de la table (par exemple, le résultat de la SHOW MEASURES requête) est le suivant :

nom_mesure data_type Dimensions
événements multi [{"data_type » « varchar », « dimension_name » « availability_zone »}, {"data_type » « varchar », « dimension_name » « microservice_name »}, {"data_type » varchar », « dimension_name » 1_instance_name «}, {" data_type » « varchar », « dimension_name » _name "}, {" data_type » ̈varchar », « dimension_name » ̈jdk_version "}, {" data_type » ̈varchar », « dimension_name » ̈varchar », « dimension_name » ̈varchar », « dimension_name » ̈region «}, {" data_type » ̈varchar », « dimension_name » ̈silo}]
metrics multi [{"data_type » « varchar », « dimension_name » « availability_zone »}, {"data_type » « varchar », « dimension_name » « microservice_name »}, {"data_type » varchar », « dimension_name » 1_instance_name «}, {" data_type » .varchar », « dimension_name » _version "}, {" data_type » ̈varchar », « dimension_name » ̈cell "}, {" data_type » ̈varchar », « dimension_name » ̈region «}, {" data_type » ̈varchar », « dimension_name » ̈silo «}, {" data_type » ̈varchar », « dimension_name » ̈instance_type}]

Dans ce cas, vous pouvez constater que les événements et les métriques ont également des ensembles de dimensions différents, les événements ayant des dimensions différentes jdk_version et process_name tandis que les métriques ont les dimensions instance_type et os_version.

L'utilisation de différents noms de mesures vous permet d'écrire des requêtes avec des prédicats, par exemple WHERE measure_name = 'metrics' pour obtenir uniquement les métriques. De plus, le fait d'avoir toutes les données émises par la même instance dans la même table implique que vous pouvez également écrire une requête plus simple avec le prédicat instance_name pour obtenir toutes les données de cette instance. Par exemple, un prédicat du formulaire WHERE instance_name = ‘instance-1234’ sans prédicat measure_name renverra toutes les données d'une instance de serveur spécifique.

Recommandations pour le partitionnement des enregistrements à mesures multiples

Important

Cette section est obsolète !

Ces recommandations sont périmées. Le partitionnement est désormais mieux contrôlé à l'aide de clés de partition définies par le client.

Nous avons constaté que l'écosystème des séries chronologiques comporte un nombre croissant de charges de travail qui nécessitent d'ingérer et de stocker d'énormes quantités de données, tout en nécessitant des réponses à des requêtes à faible latence lors de l'accès aux données via un ensemble de valeurs de dimension à cardinalité élevée.

En raison de ces caractéristiques, les recommandations de cette section seront utiles pour les charges de travail des clients présentant les caractéristiques suivantes.

  • Vous avez adopté ou souhaitez adopter des enregistrements à mesures multiples.

  • Attendez-vous à recevoir dans le système un volume élevé de données qui seront stockées pendant de longues périodes.

  • Exiger des temps de réponse à faible latence pour leurs principaux modèles d'accès (requêtes).

  • Sachez que les modèles de requêtes les plus importants impliquent une condition de filtrage quelconque dans le prédicat. Cette condition de filtrage est basée sur une dimension de cardinalité élevée. Par exemple, considérez les événements ou les agrégations par UserId DeviceId, ServerID, host-name, etc.

Dans ces cas, un nom unique pour toutes les mesures multi-mesures ne sera pas utile, car notre moteur utilise un nom multi-mesures pour partitionner les données et le fait d'avoir une valeur unique limite l'avantage de partition que vous obtenez. Le partitionnement de ces enregistrements repose principalement sur deux dimensions. Supposons que le temps soit indiqué sur l'axe X, qu'il y ait un hachage des noms de dimension et que le temps soit indiqué measure_name sur l'axe Y. measure_nameDans ces cas, cela fonctionne presque comme une clé de partitionnement.

Notre recommandation est la suivante.

  • Lorsque vous modélisez vos données pour des cas d'utilisation tels que celui measure_name que nous avons mentionné, utilisez un dérivé direct de votre modèle d'accès aux requêtes principal. Par exemple :

    • Votre cas d'utilisation nécessite de suivre les performances des applications et la QoE du point de vue de l'utilisateur final. Il peut également s'agir de mesures de suivi pour un seul serveur ou appareil IoT.

    • Si vous interrogez et filtrez par UserId, vous devez, au moment de l'ingestion, trouver le meilleur moyen de vous associer measure_name à UserId.

    • Étant donné qu'une table à plusieurs mesures ne peut contenir que 8 192 noms de mesures différents, la formule adoptée ne doit pas générer plus de 8 192 valeurs différentes.

  • Une approche que nous avons appliquée avec succès pour les valeurs de chaîne consiste à appliquer un algorithme de hachage à la valeur de chaîne. Effectuez ensuite l'opération modulo avec la valeur absolue du résultat du hachage et 8192.

    measure_name = getMeasureName(UserId)
    int getMeasureName(value) {
        hash_value =  abs(hash(value))
        return hash_value % 8192
    }
  • Nous avons également ajouté abs() la suppression du signe, éliminant ainsi la possibilité que les valeurs soient comprises entre -8192 et 8192. Cela doit être effectué avant l'opération du modulo.

  • En utilisant cette méthode, vos requêtes peuvent être exécutées en une fraction du temps qu'il faudrait pour exécuter un modèle de données non partitionné.

  • Lorsque vous interrogez les données, assurez-vous d'inclure une condition de filtrage dans le prédicat qui utilise la nouvelle valeur dérivée du measure_name. Par exemple :

    • SELECT * FROM your_database.your_table WHERE host_name = 'Host-1235' time BETWEEN '2022-09-01' AND '2022-09-18' AND measure_name = (SELECT cast(abs(from_big_endian_64(xxhash64(CAST('HOST-1235' AS varbinary))))%8192 AS varchar))
    • Cela réduira le nombre total de partitions numérisées pour obtenir des données qui se traduiront par des requêtes plus rapides au fil du temps.

N'oubliez pas que si vous souhaitez bénéficier des avantages de ce schéma de partition, le hachage doit être calculé côté client et transmis à Timestream LiveAnalytics sous forme de valeur statique au moteur de requête. L'exemple précédent fournit un moyen de valider que le hachage généré peut être résolu par le moteur en cas de besoin.

time host_name location type_serveur cpu_usage mémoire_disponible temp du processeur

05.09-07 21:48:44.000000000

hôte-1235

us-east1

5,8 xl

55

16,2

78

RK09-07 21:48:44.000000000

hôte-3587

us-west1

5,8 xl

62

18.1

81

2_09-07 21:48:45 000 000000

hôte-258743

central de l'UE

5,8 xl

88

9,4

91

05.09-07 21:48:45.000000000

hôte-35654

us-east2

5,8 xl

29

24

54

RK09.07 21:48:45,000000000

hôte-254

us-west1

5,8 xl

44

32

48

Pour générer le résultat associé measure_name conformément à nos recommandations, il existe deux voies qui dépendent de votre schéma d'ingestion.

  1. Pour l'ingestion par lots de données historiques : vous pouvez ajouter la transformation à votre code d'écriture si vous utilisez votre propre code pour le traitement par lots.

    En s'appuyant sur l'exemple précédent.

    List<String> hosts = new ArrayList<>(); hosts.add("host-1235"); hosts.add("host-3587"); hosts.add("host-258743"); hosts.add("host-35654"); hosts.add("host-254"); for (String h: hosts){ ByteBuffer buf2 = ByteBuffer.wrap(h.getBytes()); partition = abs(hasher.hash(buf2, 0L)) % 8192; System.out.println(h + " - " + partition); }

    Sortie

    host-1235 - 6445
    host-3587 - 6399
    host-258743 - 640
    host-35654 - 2093
    host-254 - 7051
    

    Ensemble de données résultant

    time host_name location nom_mesure type_serveur cpu_usage mémoire_disponible temp du processeur

    05.09-07 21:48:44.000000000

    hôte-1235

    us-east1

    6445

    5,8 xl

    55

    16,2

    78

    RK09-07 21:48:44.000000000

    hôte-3587

    us-west1

    6399

    5,8 xl

    62

    18.1

    81

    2_09-07 21:48:45 000 000000

    hôte-258743

    central de l'UE

    640

    5,8 xl

    88

    9,4

    91

    05.09-07 21:48:45.000000000

    hôte-35654

    us-east2

    2093

    5,8 xl

    29

    24

    54

    RK09.07 21:48:45,000000000

    hôte-254

    us-west1

    7051

    5,8 xl

    44

    32

    48

  2. Pour une ingestion en temps réel : vous devez générer le fichier measure_name en vol au fur et à mesure que les données arrivent.

Dans les deux cas, nous vous recommandons de tester votre algorithme de génération de hachage aux deux extrémités (ingestion et interrogation) pour vous assurer que vous obtenez les mêmes résultats.

Voici quelques exemples de code sur host_name lesquels générer la valeur hachée.

Exemple Python
>>> import xxhash >>> from bitstring import BitArray >>> b=xxhash.xxh64('HOST-ID-1235').digest() >>> BitArray(b).int % 8192 ### 3195
Exemple Go
package main import ( "bytes" "fmt" "github.com/cespare/xxhash" ) func main() { buf := bytes.NewBufferString("HOST-ID-1235") x := xxhash.New() x.Write(buf.Bytes()) // convert unsigned integer to signed integer before taking mod fmt.Printf("%f\n", abs(int64(x.Sum64())) % 8192) } func abs(x int64) int64 { if (x < 0) { return -x } return x }
Exemple Java
import java.nio.ByteBuffer; import net.jpountz.xxhash.XXHash64; public class test { public static void main(String[] args) { XXHash64 hasher = net.jpountz.xxhash.XXHashFactory.fastestInstance().hash64(); String host = "HOST-ID-1235"; ByteBuffer buf = ByteBuffer.wrap(host.getBytes()); Long result = Math.abs(hasher.hash(buf, 0L)); Long partition = result % 8192; System.out.println(result); System.out.println(partition); } }
Exemple dépendance dans Maven
<dependency> <groupId>net.jpountz.lz4</groupId> <artifactId>lz4</artifactId> <version>1.3.0</version> </dependency>