Para obtener capacidades similares a las de Amazon Timestream, considere Amazon Timestream LiveAnalytics para InfluxDB. Ofrece una ingesta de datos simplificada y tiempos de respuesta a las consultas en milisegundos de un solo dígito para realizar análisis en tiempo real. Obtenga más información aquí.
Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.
Modelado de datos
Amazon Timestream para LiveAnalytics está diseñado para recopilar, almacenar y analizar datos de series temporales de aplicaciones y dispositivos que emiten una secuencia de datos con una marca temporal. Para obtener un rendimiento óptimo, los datos que se envían a Timestream para LiveAnalytics deben tener características temporales y el tiempo debe ser un componente esencial de los datos.
Timestream para LiveAnalytics le proporciona la flexibilidad para modelar sus datos de diferentes maneras para adaptarlos a los requisitos de su aplicación. En esta sección, abordamos varios de estos patrones y proporcionamos pautas para que pueda optimizar sus costos y el rendimiento. Familiarícese con Amazon LiveAnalytics Timestream para conceptos clave como las dimensiones y las medidas. En esta sección, obtendrá más información sobre lo siguiente al momento de decidir si desea crear una o varias tablas para almacenar datos:
-
Qué datos incluir en la misma tabla frente a cuándo desea separar los datos en varias tablas y bases de datos.
-
Cómo elegir entre los registros de varias medidas de Timestream para LiveAnalytics en comparación con los registros de una sola medida y los beneficios de modelar con registros de varias medidas, especialmente cuando su aplicación rastrea varias mediciones al mismo tiempo y al instante.
-
Qué atributos modelar como dimensiones o como medidas.
-
Cómo utilizar de forma eficaz los atributos del nombre de la medida para optimizar la latencia de sus consultas.
Temas
Tabla única frente a tablas múltiples
Al modelar los datos en la aplicación, otro aspecto importante es cómo modelar los datos en tablas y en bases de datos. Las bases de datos y las tablas en Timestream para LiveAnalytics son abstracciones para el control de acceso, que especifican las claves de KMS, los periodos de retención, etc. Timestream para LiveAnalytics divide de forma automática los datos y está diseñado para escalar los recursos de forma que se adapten a la carga de la ingesta, el almacenamiento y las consultas, así como a los requisitos de sus aplicaciones.
Una tabla de Timestream para LiveAnalytics puede escalar a petabytes de datos almacenados y a decenas de gigabytes por segundo de escritura de datos. Las consultas pueden procesar cientos de terabytes por hora. Las consultas de Timestream para LiveAnalytics pueden abarcar varias tablas y bases de datos, lo que proporciona combinaciones y uniones para ofrecer un acceso sin problemas a los datos de varias tablas y bases de datos. Por lo tanto, la escala de los datos o los volúmenes de solicitudes no suelen ser la preocupación principal a la hora de decidir cómo organizar los datos en Timestream para LiveAnalytics. A continuación, se incluyen algunas consideraciones importantes a la hora de decidir qué datos colocar en la misma tabla en comparación con los de tablas diferentes o tablas en diferentes bases de datos.
-
Las políticas de retención de datos (retención del almacenamiento de memoria, retención del almacenamiento magnético, etc.) se admiten con la granularidad de una tabla. Por ende, los datos que requieren políticas de retención diferentes deben estar en tablas diferentes.
-
Las claves de AWS KMS que se utilizan para cifrar sus datos están configuradas en el nivel de base de datos. Por lo tanto, los distintos requisitos de clave de cifrado implican que los datos deberán estar en bases de datos diferentes.
-
Timestream para LiveAnalytics admite el control de acceso basado en los recursos con la granularidad de las tablas y bases de datos. Tenga en cuenta los requisitos de control de acceso a la hora de decidir qué datos escribir en la misma tabla o en tablas diferentes.
-
Tenga en cuenta los límites del número de dimensiones, nombres de medidas y nombres de atributos de múltiples medidas a la hora de decidir qué datos se almacenan en qué tabla.
-
Tenga en cuenta la carga de trabajo de las consultas y los patrones de acceso al momento de decidir cómo organizar los datos, ya que la latencia de las consultas y la facilidad de redacción de las consultas dependerán de ello.
-
Si guarda los datos que consulta con frecuencia en la misma tabla, esto suele facilitar la redacción de las consultas y, normalmente, evitar tener que escribir combinaciones, uniones o expresiones de tabla comunes. Esto también suele tener como resultado una latencia de consultas más baja. Puede usar predicados en los nombres de las dimensiones y las medidas para filtrar los datos relevantes para las consultas.
Por ejemplo, considere un caso en el que almacena datos de dispositivos ubicados en seis continentes. Si sus consultas acceden con frecuencia a datos de todos los continentes para obtener una vista global agregada, almacenar los datos de estos continentes en la misma tabla hará que las consultas se escriban de manera más sencilla. Por otro lado, si almacena datos en tablas diferentes, puede combinar los datos en la misma consulta; sin embargo, tendrá que escribir una consulta para unir los datos de todas las tablas.
-
Timestream para LiveAnalytics utiliza las particiones y la indexación adaptables de los datos, por lo que a las consultas solo se les cobra por los datos que son relevantes para ellas. Por ejemplo, si tiene una tabla que almacena datos de un millón de dispositivos en seis continentes, si su consulta tiene predicados del formulario
WHERE device_id = 'abcdef'oWHERE continent = 'North America', las consultas solo se cobran por los datos del dispositivo o del continente. -
Siempre que sea posible, si utiliza el nombre de la medida para separar los datos de la misma tabla que no se emiten al mismo tiempo o que no se consultan con frecuencia, si utiliza predicados como
WHERE measure_name = 'cpu'en su consulta, no solo obtiene los beneficios de la medición, sino que Timestream para LiveAnalytics también puede eliminar de forma eficaz las particiones que no tienen el nombre de medida utilizado en el predicado de la consulta. Esto le permite almacenar datos relacionados con diferentes nombres de medidas en la misma tabla, sin que ello afecte la latencia de las consultas ni los costos, y evita la dispersión de los datos en varias tablas. El nombre de la medida se usa básicamente para particionar los datos y eliminar las particiones que no son relevantes para la consulta.
-
Registros de medidas múltiples frente a registros de medida única
Timestream para LiveAnalytics le permite escribir datos con varias medidas por registro (medidas múltiples) o una sola medida por registro (medida única).
Registros de medidas múltiples
En muchos casos de uso, un dispositivo o una aplicación que esté rastreando puede emitir varias métricas o eventos al mismo tiempo. En esos casos, puede almacenar todas las métricas emitidas en la misma marca de tiempo en el mismo registro de medidas múltiples. Es decir, todas las medidas almacenadas en el mismo registro de medidas múltiples aparecen como columnas diferentes en la misma fila de datos.
Tenga en cuenta, por ejemplo, que su aplicación emite métricas como CPU, memoria y disk_iops desde un dispositivo medidas en el mismo instante. El siguiente es un ejemplo de una tabla de este tipo donde varias métricas emitidas al mismo tiempo se almacenan en la misma fila. Verá que dos hosts emiten las métricas una vez por segundo.
| Hostname | measure_name | Time | cpu | Memoria | disk_iops |
|---|---|---|---|---|---|
| host-24Gju | métricas | 2021-12-01 19:00:00 | 35 | 54,9 | 38,2 |
| host-24Gju | métricas | 2021-12-01 19:00:01 | 36 | 58 | 39 |
| host-28Gju | métricas | 2021-12-01 19:00:00 | 15 | 55 | 92 |
| host-28Gju | métricas | 2021-12-01 19:00:01 | 16 | 50 | 40 |
Registros de medida única
Los registros de medida única son adecuados cuando los dispositivos emiten diferentes métricas en diferentes periodos de tiempo, o si se utiliza una lógica de procesamiento personalizada que emite métricas o eventos en diferentes periodos de tiempo (por ejemplo, cuando cambia la lectura o el estado de un dispositivo). Como cada medida tiene una marca de tiempo única, las medidas se pueden almacenar en sus propios registros en Timestream para LiveAnalytics. Por ejemplo, consideremos un sensor de IoT, que rastrea la temperatura y la humedad del suelo, que emite un registro solo cuando detecta un cambio con respecto a la entrada que se informó anteriormente. A continuación, se proporciona un ejemplo de la emisión de dichos datos mediante registros de una medida única.
| device_id | measure_name | Time | measure_value::double | measure_value::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 | humedad | 2021-12-01 19:05:30 | NULL | 21 |
| sensor-sea478 | humedad | 2021-12-01 19:00:01 | NULL | 23 |
Comparación de registros de una medida única y de múltiples medidas
Timestream para LiveAnalytics le proporciona la flexibilidad de modelar sus datos como registros de una o múltiples medidas, en función de los requisitos y las características de su aplicación. Una sola tabla puede almacenar registros de una o múltiples medidas si así lo desean los requisitos de su aplicación. En general, cuando la aplicación emite múltiples medidas o eventos al mismo tiempo y en un instante, se recomienda modelar los datos como registros de múltiples medidas para obtener un acceso eficiente a los datos y un almacenamiento de datos rentable.
Por ejemplo, si considera un caso de uso de DevOps que rastrea métricas y eventos
-
Medición de ingesta: los registros de medidas múltiples producen aproximadamente un 40 % menos de ingesta de bytes escritos.
-
Procesamiento por lotes de ingesta: los registros que se miden varias veces dan como resultado el envío de lotes de datos más grandes, lo que implica que los clientes necesitan menos subprocesos y menos CPU para procesar la ingesta.
-
Medición del almacenamiento: los registros con múltiples medidas reducen aproximadamente 8 veces la capacidad de almacenamiento, lo que se traduce en un importante ahorro de almacenamiento tanto en memoria como en almacenamiento magnético.
-
Latencia de consulta: los registros de medidas múltiples dan como resultado una latencia de consulta más baja para la mayoría de los tipos de consultas en comparación con los registros de medida única.
-
Bytes medidos por consulta: en el caso de las consultas que escanean menos de 10 MB de datos, se pueden comparar tanto los registros de medida única como los de múltiples medidas. Para las consultas que acceden a una medida única y escanean más de 10 MB de datos, los registros de medida única suelen tener como resultado bytes medidos más bajos. Para las consultas que hacen referencia a tres o más medidas, los registros de varias medidas dan como resultado una medición más baja de bytes.
-
Facilidad de expresar consultas de medidas múltiples: cuando las consultas hacen referencia a medidas múltiples, modelar los datos con registros de medidas múltiples da como resultado consultas más compactas y fáciles de escribir.
Los factores anteriores variarán en función del número de métricas que usted hace el seguimiento, del número de dimensiones que tengan sus datos, etc. Si bien en el ejemplo anterior se proporcionan algunos datos concretos, en muchas situaciones de aplicación y casos de uso se han observado casos de uso en los que, si la aplicación emite múltiples medidas al mismo tiempo, es más eficaz almacenar los datos como registros de múltiples medidas. Además, los registros de múltiples medidas proporcionan la flexibilidad de los tipos de datos y almacenan varios valores más como contexto (por ejemplo, almacenan los identificadores de solicitud y las marcas de tiempo adicionales, los cuales se analizarán más adelante).
Tenga en cuenta que un registro de múltiples medidas también puede modelar medidas dispersas, como en el ejemplo anterior, para registros de una única medida: puede usar el measure_name para almacenar el nombre de la medida y usar un nombre de atributo genérico de múltiples medidas, por ejemplo value_double para almacenar medidas DOUBLE, value_bigint para almacenar medidas BIGINT, value_timestamp para almacenar valores de TIMESTAMP adicionales, etc.
Dimensiones y medidas
Una tabla en Timestream para LiveAnalytics le permite almacenar dimensiones (identificando los atributos del dispositivo o los datos que está almacenando) y medidas (las métricas o los valores que está rastreando); consulte Amazon LiveAnalytics Timestream para conceptos para obtener más información. A medida que modele su aplicación en Timestream para LiveAnalytics, la forma en que mapee sus datos en dimensiones y medidas afectará la latencia de ingesta y de consultas. Las siguientes son pautas sobre cómo modelar sus datos como dimensiones y medidas, y que puede aplicar a su caso de uso.
Selección de dimensiones
Los datos que identifican la fuente que envía los datos de serie temporal se adaptan perfectamente a las dimensiones, que son atributos que no cambian con el tiempo. Por ejemplo, si tiene un servidor que emite métricas, los atributos que lo identifican, como el nombre de host, la región, el bastidor y la zona de disponibilidad, son aptos para las dimensiones. Del mismo modo, para un dispositivo de IoT con varios sensores que informan datos de serie temporal, atributos como el identificador del dispositivo y el identificador del sensor son candidatos para las dimensiones.
Si escribe los datos como registros de múltiples medidas, las dimensiones y los atributos de múltiples medidas aparecen como columnas en la tabla cuando realiza DESCRIBE o ejecuta una declaración SELECT en la tabla. Por lo tanto, al escribir las consultas, puede utilizar libremente las dimensiones y las medidas de la misma consulta. Sin embargo, al crear el registro de escritura para ingerir datos, tenga en cuenta lo siguiente al momento de elegir qué atributos se especifican como dimensiones y cuáles son valores de medida:
-
Los nombres y los valores de las dimensiones, el nombre de la medida y la marca de tiempo identifican de forma exclusiva los datos de serie temporal. Timestream para LiveAnalytics utiliza este identificador único para desduplicar de forma automática los datos. Es decir, si Timestream para LiveAnalytics recibe dos puntos de datos con los mismos valores de nombres de dimensiones, valores de dimensión, nombre de medida y marca de tiempo, y los valores tienen el mismo número de versión, Timestream para LiveAnalytics desduplica. Si la solicitud de escritura nueva tiene una versión inferior a los datos que ya existen en Timestream para LiveAnalytics, se rechaza la solicitud de escritura. Si la nueva solicitud de escritura tiene una versión superior, entonces el valor nuevo sobreescribe el valor anterior. Por lo tanto, la forma en que elija los valores de las dimensiones afectará a este comportamiento de desduplicación.
-
Los nombres y los valores de las dimensiones no se pueden actualizar, pero el valor de la medida sí. Por lo tanto, es mejor modelar cualquier dato que pueda necesitar actualizaciones como valores de medida. Por ejemplo, si tiene una máquina en la fábrica cuyo color puede cambiar, puede modelar el color como un valor de medición, a menos que también desee utilizar el color como atributo de identificación necesario para la desduplicación. Es decir, los valores de medición se pueden usar para almacenar atributos que solo cambian lentamente con el tiempo.
Tenga en cuenta que una tabla de Timestream para LiveAnalytics no limita el número de combinaciones únicas de nombres y valores de dimensiones. Por ejemplo, puede almacenar en una tabla miles de millones de estas combinaciones de valores únicos. Sin embargo, como verá en los siguientes ejemplos, la elección cuidadosa de las dimensiones y las medidas puede optimizar considerablemente la latencia de las solicitudes, especialmente en el caso de las consultas.
Identificadores únicos en las dimensiones
Si la situación de su aplicación requiere que almacene un identificador único para cada punto de datos (por ejemplo, un identificador de solicitud, un identificador de transacción o un identificador de correlación), modelar el atributo de identificador como un valor de medida permitirá mejorar considerablemente la latencia de las consultas. Al modelar los datos con registros de varias medidas, el identificador aparece en la misma fila en el contexto del resto de los datos de dimensiones y de serie temporal, para que las consultas puedan seguir utilizándolos de forma eficaz. Por ejemplo, considerando un caso de uso de DevOps
Puede utilizar una analogía similar para los atributos que no son completamente únicos para cada punto de datos, pero que tienen cientos de miles o millones de valores únicos. Puede modelar esos atributos como dimensiones o como valores de medida. Debería modelarlo como una dimensión si los valores son necesarios para la desduplicación en la ruta de escritura, como se ha explicado anteriormente, o si lo utiliza con frecuencia como predicado (por ejemplo, en la cláusula WHERE con un predicado de igualdad sobre un valor de ese atributo, por ejemplo device_id = 'abcde', si su aplicación rastrea millones de dispositivos) en sus consultas.
Riqueza en los tipos de datos con registros de múltiples medidas
Los registros de múltiples medidas le proporcionan la flexibilidad necesaria para modelar sus datos de forma eficaz. Los datos que se almacenan en un registro de múltiples medidas aparecen en la tabla como columnas similares a las dimensiones, lo que proporciona la misma facilidad a la hora de consultar los valores de las dimensiones y las medidas. Ha visto algunos de estos patrones en los ejemplos que se escribieron anteriormente. A continuación, encontrará patrones adicionales para utilizar de forma eficaz los registros de múltiples medidas a fin de adaptarse a los casos de uso de su aplicación.
Los registros de múltiples medidas admiten los atributos de los tipos de datos DOUBLE, BIGINT, VARCHAR, BOOLEAN y TIMESTAMP. Por lo tanto, se adaptan naturalmente a los diferentes tipos de atributos:
-
Información de ubicación: por ejemplo, si desea rastrear una ubicación (expresada como latitud y longitud), modelarla como un atributo de múltiples medidas tendrá como resultado una latencia de consulta más baja en comparación con almacenarlas como dimensiones
VARCHAR, especialmente si tiene predicados sobre las latitudes y longitudes. -
Varias marcas de tiempo en un registro: si la situación de su aplicación requiere que realice un seguimiento de varias marcas de tiempo para un registro de serie temporal, puede modelarlas como atributos adicionales en el registro de múltiples medidas. Este patrón se puede usar para almacenar datos con marcas de tiempo futuras o pasadas. Tenga en cuenta que todos los registros seguirán utilizando la marca de tiempo de la columna de tiempo para particionar, indexar e identificar de forma única un registro.
En particular, si tiene datos numéricos o marcas de tiempo en las que se utilizan predicados en la consulta, modelar esos atributos como atributos de múltiples medidas y no como dimensiones reducirá la latencia de la consulta. Esto se debe a que, al modelar dichos datos con los tipos de datos enriquecidos compatibles con los registros de múltiples medidas, puede expresar los predicados mediante tipos de datos nativos en lugar de convertir los valores de VARCHAR a otro tipo de datos si ha modelado dichos datos como dimensiones.
Uso del nombre de medidas con registros de múltiples medidas
Las tablas de Timestream para LiveAnalytics admiten un atributo (o columna) especial denominado nombre de medida. Debe especificar un valor para este atributo para cada registro que escriba en Timestream para LiveAnalytics. En el caso de los registros de una medida única, es normal utilizar el nombre de la métrica (por ejemplo, CPU o memoria para las métricas del servidor, o temperatura o presión para las métricas de los sensores). Cuando se utilizan registros de múltiples medidas, los atributos de un registro de múltiples medidas reciben un nombre y estos se convierten en nombres de columnas de la tabla. Por lo tanto, la CPU, la memoria, la temperatura y la presión pueden convertirse en nombres de atributos de múltiples medidas. Una pregunta natural es cómo utilizar de forma eficaz el nombre de la medida.
Timestream para LiveAnalytics utiliza los valores del atributo del nombre de la medida para particionar e indexar los datos. Por lo tanto, si una tabla tiene varios nombres de medida diferentes y si las consultas utilizan esos valores como predicados de consulta, Timestream para LiveAnalytics puede utilizar su particionamiento e indexación personalizados para eliminar los datos que no son relevantes para las consultas. Por ejemplo, si la tabla tiene nombres de medidas cpu y memory, y la consulta tiene un predicado WHERE
measure_name = 'cpu', Timestream para LiveAnalytics puede recortar de forma eficaz los datos de los nombres de medidas que no son relevantes para la consulta, por ejemplo, las filas con memoria de nombres de medidas en este ejemplo. Esta reducción se aplica incluso cuando se utilizan nombres de medidas con registros de múltiples medidas. Puede utilizar el atributo de nombre de medida de forma eficaz como atributo de partición de una tabla. El nombre de la medida junto con los nombres y los valores de las dimensiones y el tiempo se utilizan para particionar los datos en una tabla de Timestream para LiveAnalytics. Tenga en cuenta los límites del número de nombres de medida únicos permitidos en una tabla de Timestream para LiveAnalytics. Además, tenga en cuenta que el nombre de una medida también está asociado a un tipo de datos de valor de medida. Por ejemplo, el nombre de una sola medida solo se puede asociar a un tipo de valor de medida. Ese tipo puede ser uno de los siguientes: DOUBLE, BIGINT, BOOLEAN, VARCHAR o MULTI. Los registros de múltiples medidas almacenados con un nombre de medida tendrán el tipo de datos de MULTI. Como un único registro de múltiples medidas puede almacenar múltiples métricas con diferentes tipos de datos (DOUBLE, BIGINT, VARCHAR, BOOLEAN y TIMESTAMP), puede asociar datos de diferentes tipos en un registro de múltiples medidas.
En las siguientes secciones, se describen algunos ejemplos diferentes de cómo se puede utilizar de forma eficaz el atributo de nombre de la medida para agrupar distintos tipos de datos en la misma tabla.
Sensores de IoT que informan calidad y valor
Suponga que tiene una aplicación que supervisa los datos de los sensores de IoT. Cada sensor registra diferentes medidas, como la temperatura y presión. Además de los valores reales, los sensores también indican la calidad de las mediciones, la cual una medida de la precisión de la lectura y una unidad de medición. Dado que la calidad, la unidad y el valor se emiten juntos, se pueden modelar como registros de múltiples medidas, como se muestra en el siguiente ejemplo de datos, donde device_id se muestra una dimensión y quality, value y unit son atributos de múltiples medidas:
| device_id | measure_name | Time | Calidad | Valor | Unidad |
|---|---|---|---|---|---|
| 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 | 2021-12-01 19:05:30 | 98 | 31 | psi |
| sensor-sea478 | pressure | 2021-12-01 19:00:01 | 24 | 132 | psi |
Este enfoque le permite combinar los beneficios de los registros de múltiples medidas con la partición y depuración de los datos mediante los valores del nombre de la medida. Si las consultas hacen referencia a una sola medida, como la temperatura, puede incluir un predicado measure_name en la consulta. El siguiente es un ejemplo de una consulta de este tipo, que también proyecta la unidad para las mediciones cuya calidad es superior a 90.
SELECT device_id, time, value AS temperature, unit FROM db.table WHERE time > ago(1h) AND measure_name = 'temperature' AND quality > 90
El uso del predicado measure_name en la consulta permite a Timestream para LiveAnalytics eliminar de forma eficaz las particiones y los datos que no son relevantes para la consulta, lo que mejora la latencia de la consulta.
También es posible almacenar todas las métricas en el mismo registro de múltiples medidas si todas se emiten en la misma fecha o si se consultan varias métricas juntas en la misma consulta. Por ejemplo, puede crear un registro de múltiples medidas con atributos como los siguientes: temperature_quality, temperature_value, temperature_unit, pressure_quality, pressure_value y pressure_unit. Muchos de los puntos debatidos anteriormente sobre el modelado de datos mediante registros de una sola medida frente a registros de múltiples medidas se aplican a la decisión de cómo modelar los datos. Tenga en cuenta los patrones de acceso a las consultas y la forma en que se generan los datos para elegir un modelo que optimice los costos, la latencia de ingesta y consulta, y la facilidad de redacción de las consultas.
Diferentes tipos de métricas en la misma tabla
Otro caso de uso en el que puede combinar registros de múltiples medidas con valores de nombres de medidas es modelar diferentes tipos de datos que se emiten de forma independiente desde el mismo dispositivo. Considere el caso de uso de la supervisión de DevOps, en el que los servidores emiten dos tipos de datos: métricas emitidas de forma regular y eventos irregulares. Un ejemplo de este enfoque es el esquema descrito en el generador de datos que modela un caso de uso de DevOpsSHOW MEASURES) es:
| measure_name | data_type | Dimensiones |
|---|---|---|
| eventos | multi | [{"data_type":"varchar","dimension_name":"availability_zone"},{"data_type":"varchar","dimension_name":"microservice_name"},{"data_type":"varchar","dimension_name":"instance_name"},{"data_type":"varchar","dimension_name":"process_name"},{"data_type":"varchar","dimension_name":"jdk_version"},{"data_type":"varchar","dimension_name":"cell"},{"data_type":"varchar","dimension_name":"region"},{"data_type":"varchar","dimension_name":"silo"}] |
| métricas | multi | [{"data_type":"varchar","dimension_name":"availability_zone"},{"data_type":"varchar","dimension_name":"microservice_name"},{"data_type":"varchar","dimension_name":"instance_name"},{"data_type":"varchar","dimension_name":"os_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"}] |
En este caso, puede ver que los eventos y las métricas también tienen diferentes conjuntos de dimensiones, donde los eventos tienen dimensiones diferentes jdk_version y process_name; mientras las métricas tienen dimensiones instance_type y os_version.
El uso de diferentes nombres de medida le permite escribir consultas con predicados, por ejemplo, WHERE measure_name = 'metrics' para obtener solo las métricas. Además, tener todos los datos emitidos desde la misma instancia en la misma tabla implica que también puede escribir una consulta más sencilla con el predicado instance_name para obtener todos los datos de esa instancia. Por ejemplo, un predicado del formulario WHERE instance_name =
'instance-1234' sin un predicado measure_name devolverá todos los datos de una instancia de servidor específica.
Recomendaciones para la partición de registros de múltiples medidas
importante
Esta sección ya no está disponible.
Estas recomendaciones no están actualizadas. El particionamiento ahora se controla mejor mediante claves de partición definidas por el cliente.
Hemos observado que hay un número creciente de cargas de trabajo en el ecosistema de series temporales que requieren la ingesta y el almacenamiento de enormes cantidades de datos y, al mismo tiempo, requieren respuestas a consultas de baja latencia cuando se accede a los datos a través un conjunto de valores de dimensión de alta cardinalidad.
Debido a estas características, las recomendaciones de esta sección resultarán útiles para las cargas de trabajo de los clientes que tengan lo siguiente:
-
Hayan adoptado o deseen adoptar registros de múltiples medidas.
-
Esperen recibir un gran volumen de datos en el sistema que se almacenarán durante periodos prolongados.
-
Requieren tiempos de respuesta de baja latencia para sus patrones de acceso principales (consulta).
-
Tenga en cuenta que los patrones de consultas más importantes implican algún tipo de condición de filtrado en el predicado. Esta condición de filtrado se basa en una dimensión de alta cardinalidad. Por ejemplo, considere los eventos o las agregaciones por UserID, DeviceID, ServerID, host-name, etc.
En estos casos, un nombre único para todas las medidas de varias medidas no servirá de nada, ya que nuestro motor utiliza nombres de varias medidas para particionar los datos, y tener un único valor limita la ventaja de partición que se obtiene. La partición de estos registros se basa principalmente en dos dimensiones. Digamos que el tiempo se encuentra en el eje X y un hash de nombres de dimensión y measure_name se encuentran en el eje Y. En estos casos, measure_name funciona casi como una clave de partición.
Nuestra recomendación es la siguiente:
-
Cuando modele sus datos para casos de uso como el que mencionamos, utilice un patrón
measure_nameque sea un derivado directo del patrón de acceso a las consultas principales. Por ejemplo:-
Su caso de uso requiere hacer un seguimiento del rendimiento de las aplicaciones y de la QoE desde el punto de vista del usuario final. Esto también podría ser el seguimiento de las mediciones de un solo servidor o un dispositivo de IoT.
-
Si está consultando y filtrando por UserId, necesitará, en el momento de la ingesta, encontrar la mejor manera de asociar
measure_namea UserID. -
Como una tabla de múltiples medidas solo puede contener 8192 nombres de medidas diferentes, sea cual sea la fórmula que se adopte, no debería generar más de 8192 valores diferentes.
-
-
Un enfoque que aplicamos con éxito a los valores de cadena es aplicar un algoritmo de hash al valor de cadena. A continuación, realice la operación de módulo con el valor absoluto del resultado del hash y 8192.
measure_name = getMeasureName(UserId) int getMeasureName(value) { hash_value = abs(hash(value)) return hash_value % 8192 } -
También hemos añadido
abs()para borrar el signo y eliminar la posibilidad de que los valores oscilen entre -8192 y 8192. Esto debe realizarse antes de la operación del módulo. -
Con este método, las consultas pueden ejecutarse en una fracción de tiempo que tardarían en ejecutarse en un modelo de datos sin particiones.
-
Al consultar los datos, asegúrese de incluir una condición de filtrado en el predicado que utilice el valor recién derivado de
measure_name. Por ejemplo:-
SELECT * FROMyour_database.your_tableWHERE 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)) -
Esto minimizará el número total de particiones escaneadas para obtener datos que, con el tiempo, se traducirán en consultas más rápidas.
-
Tenga en cuenta que, si desea aprovechar los beneficios de este esquema de particiones, el hash debe calcularse en el lado del cliente y pasarse a Timestream para LiveAnalytics como un valor estático para el motor de consultas. El ejemplo anterior ofrece una forma de validar que el motor pueda resolver el hash generado cuando sea necesario.
| hora | host_name | ubicación | server_type | cpu_usage | available_memory | cpu_temp |
|---|---|---|---|---|---|---|
|
2022-09-07 21:48:44 .000000000 |
host-1235 |
us-east1 |
5,8xl |
55 |
16,2 |
78 |
|
R2022-09-07 21:48:44 .000000000 |
host-3587 |
us-west1 |
5,8xl |
62 |
18,1 |
81 |
|
2022-09-07 21:48:45.000000000 |
host-258743 |
eu-central |
5,8xl |
88 |
9,4 |
91 |
|
2022-09-07 21:48:45 .000000000 |
host-35654 |
us-east2 |
5,8xl |
29 |
24 |
54 |
|
R2022-09-07 21:48:45 .000000000 |
host-254 |
us-west1 |
5,8xl |
44 |
32 |
48 |
Para generar los measure_name asociados siguiendo nuestra recomendación, hay dos rutas que dependen de su patrón de ingesta.
-
Para la ingesta por lotes de datos históricos: puede agregar la transformación al código de escritura si va a utilizar su propio código para el proceso por lotes.
Partiendo del ejemplo anterior.
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); }Output
host-1235 - 6445 host-3587 - 6399 host-258743 - 640 host-35654 - 2093 host-254 - 7051
Conjunto de datos resultante
hora host_name ubicación measure_name server_type cpu_usage available_memory cpu_temp 2022-09-07 21:48:44 .000000000
host-1235
us-east1
6445
5,8xl
55
16,2
78
R2022-09-07 21:48:44 .000000000
host-3587
us-west1
6399
5,8xl
62
18,1
81
2022-09-07 21:48:45.000000000
host-258743
eu-central
640
5,8xl
88
9,4
91
2022-09-07 21:48:45 .000000000
host-35654
us-east2
2093
5,8xl
29
24
54
R2022-09-07 21:48:45 .000000000
host-254
us-west1
7051
5,8xl
44
32
48
-
Para la ingesta en tiempo real: es necesario generar
measure_nameen tránsito a medida que van llegando los datos.
En ambos casos, le recomendamos que pruebe su algoritmo de generación de hash en ambos extremos (ingesta y consulta) para asegurarse de que está obteniendo los mismos resultados.
Estos son algunos ejemplos de código para generar el valor en hash basado en host_name.
ejemplo Python
>>> import xxhash >>> from bitstring import BitArray >>> b=xxhash.xxh64('HOST-ID-1235').digest() >>> BitArray(b).int % 8192 ### 3195
ejemplo 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 }
ejemplo 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); } }
ejemplo dependencia en Maven
<dependency> <groupId>net.jpountz.lz4</groupId> <artifactId>lz4</artifactId> <version>1.3.0</version> </dependency>