Esta es una funcionalidad de vista previa privada que puede cambiar de formas incompatibles con versiones anteriores en futuras versiones.
Habilite el uso del motor de tabla TimeSeries
con el SETTING
enable_time_series_table.
Ejecute el comando set enable_time_series_table = 1.El motor de tabla
TimeSeries está disponible en ClickHouse Cloud como funcionalidad de vista previa privada.
Los servicios que participan en la vista previa privada ya tienen configurado el
SETTING enable_time_series_table. Los demás servicios de ClickHouse Cloud
no cuentan con esta configuración, y no es posible habilitar el motor por su cuenta en
dichos servicios.Sintaxis
La palabra clave
SAMPLES tiene el alias DATA, y la palabra clave METRIC FAMILIES tiene el alias METRICS; ambos se mantienen por compatibilidad con versiones anteriores.
La definición de una tabla de una version anterior a 4 se escribe con METRICS, de modo que un servidor más antiguo pueda leerla.Uso
Es más fácil empezar con la configuración predeterminada (se puede crear una tablaTimeSeries sin especificar una lista de columnas):
Columnas externas
Las columnas de una tabla TimeSeries se generan automáticamente. Son columnas externas: no almacenan datos, solo proporcionan la interfaz para SELECT/INSERT. Los datos reales se almacenan en las tablas de destino. Aquí está la lista de las columnas externas:
Ejemplo:
metric_name esté vacío durante la inserción, lo que significa que el nombre de la métrica se especifica en tags con __name__, por ejemplo:
metric_family, type, unit y help:
Especificación de columnas externas
La columna externasamples se puede incluir explícitamente en una sentencia CREATE TABLE para sobrescribir su tipo predeterminado Array(Tuple(DateTime64(3), Float64)) (también se acepta su nombre anterior time_series). ClickHouse extrae de la tupla los tipos de marca de tiempo y escalares, y los propaga a la tabla interna de muestras:
timestamp y value en la cláusula INNER COLUMNS de samples:
CREATE TABLE, los tipos declarados deben coincidir.
Tablas de destino
Una tablaTimeSeries no tiene datos propios; todo se almacena en sus tablas de destino.
Esto es similar al funcionamiento de una vista materializada,
con la diferencia de que una vista materializada tiene una sola tabla de destino,
mientras que una tabla TimeSeries tiene tres tablas de destino obligatorias llamadas samples, etiqueta y familia de métricas,
y una tabla de destino opcional muestra reciente que está habilitada de forma predeterminada
(consulte la configuración recent_samples_ttl_seconds).
Las tablas de destino pueden especificarse explícitamente en la consulta CREATE TABLE
o el motor de tabla TimeSeries puede generar automáticamente tablas de destino internas.
Las filas insertadas en una tabla TimeSeries se transforman, se dividen en bloques y se insertan en estas tablas de destino.
Las tablas de destino son las siguientes:
Tabla samples
La tabla samples contiene series temporales asociadas a algún identificador. La tabla samples debe tener las siguientes columnas:
Las columnas que crea el propio motor utilizan códecs de compresión para series temporales:
timestamp CODEC(Delta, T64, ZSTD(3)) y value CODEC(ALP, ZSTD(3)). Las marcas de tiempo casi monotónicas apenas
se comprimen con códecs genéricos y, de lo contrario, pueden representar la mayor parte del tamaño en disco de la tabla samples.
El motor habilita ALP para sus tablas internas de samples y muestras recientes sin requerir que se establezca enable_alp_codec.
Consulte también Ajustar los tipos de las columnas.
Tabla de muestras recientes
La tabla de muestras recientes es opcional y está habilitada de forma predeterminada (véase el ajuste recent_samples_ttl_seconds; si se establece en cero, la tabla se deshabilita). Contiene una copia de las muestras más recientes que el TTL definido por ese ajuste, y debe tener las mismas columnas que la tabla samples. La columna generadatimestamp usa CODEC(Delta, T64, ZSTD(3)),
y la columna generada value usa CODEC(ALP, ZSTD(3)).
Cada muestra insertada se escribe tanto en la tabla de muestras como en la tabla de muestras recientes.
Las consultas cuyo rango temporal se ajusta a la ventana del TTL leen de la tabla de muestras recientes en lugar de la tabla principal de muestras,
ya que es mucho más pequeña (esto se puede deshabilitar con el ajuste a nivel de consulta time_series_prefer_recent_samples_table).
El TTL de la tabla interna de muestras recientes siempre se deriva del ajuste recent_samples_ttl_seconds.
Tabla de etiquetas
La tabla etiquetas contiene identificadores calculados para cada combinación de un nombre de métrica y etiquetas. La tabla etiquetas debe tener las siguientes columnas:
Las nuevas tablas internas de etiquetas de la versión 5 y posteriores con un motor de la familia
MergeTree tienen un índice de texto invertido sobre tags:
INDEX tags_idx tags TYPE text(tokenizer = 'keyValuePairs'). Acelera las coincidencias exactas de etiquetas como
{job="api"} en PromQL al buscar conjuntamente la clave y el valor. Las comparaciones con una cadena vacía también
coinciden con etiquetas ausentes y no utilizan este índice.
Los índices explícitos declarados en TAGS INNER COLUMNS sustituyen al índice predeterminado. Las tablas existentes y las tablas de etiquetas externas
conservan sus índices; añade y materializa el índice en su tabla de destino de etiquetas para habilitarlo.
Tabla de familias de métricas
La tabla familias de métricas contiene información sobre las familias de métricas recopiladas, sus tipos y sus descripciones. Una familia de métricas es un grupo de métricas con el mismo nombre (el tag__name__) y el mismo tipo; por ejemplo, un histogram es una familia de métricas que consta de múltiples métricas.
La tabla familias de métricas debe tener las siguientes columnas:
Creación
Existen varias formas de crear una table con el motor de tablaTimeSeries.
La sentencia más sencilla
SHOW CREATE TABLE my_table):
INNER COLUMNS. La opción recent_samples_ttl_seconds se escribió en la cláusula SETTINGS
con su valor predeterminado: la opción define el TTL de la tabla de muestras recientes, por lo que su valor efectivo queda fijado al crearla.
Además, la versión más reciente del esquema quedó fijada en la opción version (véase Control de versiones del esquema).
Las tablas internas de destino tienen nombres como .inner_id.samples.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,
.inner_id.recentsamples.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, .inner_id.tags.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,
.inner_id.metricfamilies.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
y cada tabla de destino tiene su propio conjunto de columnas:
Creación de una tabla AS a partir de una tabla existente
La sentenciaCREATE TABLE new_table AS existing_table crea una tabla TimeSeries configurada como existing_table,
que debe ser una tabla TimeSeries. Los destinos externos de existing_table no se copian: la propia sentencia debe declarar
esos destinos.
La sentencia copia de existing_table:
- la cláusula
SETTINGS, exceptoversion: la nueva tabla siempre obtiene la versión más reciente. Los ajustes especificados en la propia sentencia se combinan por nombre con los copiados, por lo que prevalece un ajuste especificado yname = DEFAULTrestablece un ajuste copiado a su valor predeterminado; - las cláusulas
INNER COLUMNSeINNER ENGINEde cada tabla interna. Se conservan las columnas personalizadas (p. ej., columnas adicionales o columnas con un códec o una expresión DEFAULT) y las partes personalizadas del motor (p. ej., un motor con argumentos, una clave de ordenación personalizada o un ajuste del motor); las demás columnas y partes del motor se ajustan a los ajustes de la nueva tabla, de modo que p. ej.,tags_to_columns,aggregate_min_time_and_max_timeotags_index_granularityespecificadas en la sentencia surtan efecto.
id, de marca de tiempo y de valor, así como el tipo de replicación de los motores internos (MergeTree,
ReplicatedMergeTree o SharedMergeTree), también se toman de existing_table, a menos que la propia sentencia los declare.
La lista de columnas externas se vuelve a generar y no se copia.
Una tabla creada con una versión anterior de ClickHouse puede utilizarse como existing_table: la nueva tabla obtiene la
estructura actual, p. ej., el tipo actual de id y la expresión de identificador predeterminada.
Ajuste de los tipos de las columnas
Puede ajustar los tipos de las columnas en las tablas internas de destino mediante la cláusulaINNER COLUMNS. Por ejemplo, para almacenar marcas de tiempo en microsegundos y valores como Float32, use:
La columna id
La columna id contiene identificadores; cada uno se calcula a partir de una combinación de un nombre de métrica y etiquetas.
El tipo y la expresión DEFAULT utilizados para generar los identificadores se pueden personalizar mediante la cláusula TAGS INNER COLUMNS:
id puede ser de cualquier tipo comparable que no sea Nullable. Los tipos de id declarados en las tablas internas de samples y etiquetas deben coincidir.
Si no se proporciona ninguna expresión DEFAULT para la columna id y la configuración id_generator no está definida, ClickHouse elegirá automáticamente la expresión DEFAULT en función del tipo de id, pero solo si el tipo de id es uno de UUID, UInt64, UInt128, FixedString(16), esos mismos tipos envueltos en LowCardinality, o una tupla de dos de esos tipos. Para dicha tupla, la expresión elegida automáticamente calcula un hash del nombre de la métrica en el primer componente y un hash de todas las etiquetas en el segundo componente.
Un tipo de identificador LowCardinality, por ejemplo Tuple(UInt64, LowCardinality(UUID)), mantiene los identificadores codificados mediante diccionario: la tabla de samples almacena pequeños diccionarios por bloque con índices de diccionario en lugar de repetir el identificador completo en cada fila, lo que reduce la cantidad de datos leídos por las consultas.
La configuración id_generator permite la misma personalización sin usar la cláusula INNER COLUMNS:
id incluso si el DEFAULT de la columna contiene otra expresión.
El tipo de la columna id también se puede especificar en la configuración id_type en lugar de en la cláusula INNER COLUMNS:
id_generator está definida, la configuración id_type se registra automáticamente en el momento del CREATE, de modo que la definición conserva el tipo para el que se escribió la expresión.
La columna tags
La columna tags contiene todas las etiquetas de una serie temporal, incluida la etiqueta __name__ con el nombre de una métrica.
La configuración tags_to_columns permite especificar que una etiqueta concreta también debe almacenarse en una columna independiente
además del mapa dentro de la columna tags:
instance y job a la tabla de destino interna etiquetas.
Los valores de las etiquetas instance y job se almacenarán tanto en esas columnas como en la columna tags.
En las tablas creadas con versiones anteriores de ClickHouse, la columna
tags contiene solo las etiquetas, sin columnas específicas
ni el nombre de la métrica, y la columna all_tags es una columna efímera que se rellenaba durante la inserción
con todas las etiquetas excepto el nombre de la métrica.Motores de las tablas internas de destino
De forma predeterminada, las tablas internas de destino usan los siguientes motores de tabla:- la tabla samples usa MergeTree;
- la tabla muestras recientes usa MergeTree particionada en buckets de 5 horas (consulte la configuración recent_samples_partition_by) con un
TTLderivado de la configuración recent_samples_ttl_seconds y conttl_only_drop_partshabilitado, de modo que las partes expiradas se eliminan por completo; - la tabla etiquetas usa AggregatingMergeTree porque los mismos datos suelen insertarse varias veces en esta tabla, por lo que hace falta una forma
de eliminar duplicados, y también porque es necesario realizar agregación para las columnas
min_timeymax_time; - la tabla familias de métricas usa ReplacingMergeTree porque los mismos datos suelen insertarse varias veces en esta tabla, por lo que hace falta una forma de eliminar duplicados.
default_table_engine:
con default_table_engine = ReplicatedMergeTree o SharedMergeTree, las tablas internas usan los motores
Replicated o Shared correspondientes. Con default_table_engine = None (o cualquier otro valor), los motores de las tablas internas
deben especificarse explícitamente.
Todas las tablas internas deben tener el mismo tipo de replicación: si una de ellas está replicada (o compartida), las demás tablas
internas también deben estar replicadas (o compartidas); de lo contrario, su contenido divergiría entre réplicas. Por ejemplo,
declarar SAMPLES INNER ENGINE = ReplicatedMergeTree(...) requiere que los demás motores internos también estén replicados,
ya sea declarados explícitamente o generados con default_table_engine = ReplicatedMergeTree.
También se pueden usar otros motores de tabla para las tablas internas de destino si así se especifica:
tags) fuera de su clave de ordenación,
algo que AggregatingMergeTree rechaza de forma predeterminada (consulte allow_dimensions_outside_sorting_key).
Esto es seguro aquí porque esas columnas dependen funcionalmente de id, que forma parte de la clave de ordenación, por lo que todas las
filas que un merge en segundo plano colapsa comparten los mismos valores. Cuando la tabla interna de etiquetas se genera o su
motor se especifica en línea como arriba, TimeSeries establece automáticamente allow_dimensions_outside_sorting_key = 1 en ella;
para una tabla de etiquetas de agregación externa creada manualmente, debe configurarlo usted mismo.
Tablas de destino externas
Es posible hacer que una tablaTimeSeries utilice una tabla creada manualmente:
RECENT SAMPLES my_recent_samples_table).
Dicha tabla debe tener las mismas columnas que una tabla externa de samples y debe conservar al menos
recent_samples_ttl_seconds segundos de datos, lo cual es responsabilidad del usuario.
Los tipos de columna de las tablas externas (id, timestamp, value y las <tag_value_column> enumeradas en tags_to_columns) deben coincidir con los que la tabla TimeSeries generaría internamente en otras circunstancias (consulte tabla Samples, tabla Etiquetas y tabla Familias de métricas para conocer las restricciones de tipo). Las discrepancias de tipo se notifican en el momento de CREATE.
El tipo de la columna id de una tabla externa de etiquetas y la expresión que genera los identificadores se registran en las configuraciones id_type e id_generator en el momento de CREATE (a partir de la version 2), de modo que la definición de la tabla TimeSeries los conserva: por ejemplo, CREATE TABLE ... AS my_table lee el tipo de id de la definición de my_table sin leer sus tablas de destino externas. Si no se especifica la configuración id_generator, se establece con el DEFAULT declarado en la columna id de la tabla externa (si existe) y, en caso contrario, con el generador canónico derivado del tipo de id. La expresión registrada se utiliza para generar id incluso si el DEFAULT de la tabla externa cambia posteriormente; consulte La columna id para obtener más detalles.
Modificar los ajustes
Se pueden modificar dos ajustes después deCREATE:
id_generatorfilter_by_min_time_and_max_time
id_generator cuando ya hay datos en la tabla de etiquetas puede generar IDs distintos para la misma combinación de métrica+etiqueta: las filas antiguas conservan sus IDs anteriores y las nuevas usan el nuevo generador.
Los demás ajustes no se pueden cambiar con ALTER ... MODIFY SETTING: la mayoría quedan incorporados en el esquema de las tablas internas en el momento de CREATE,
y el ajuste version se fija automáticamente en el momento de CREATE e identifica el propio esquema (consulta Control de versiones del esquema).
Configuración
Aquí tienes una lista de configuraciones que se pueden especificar al definir una tablaTimeSeries:
Control de versiones del esquema
El motor de tablaTimeSeries y la capa de ejecución de PromQL están en desarrollo activo:
el conjunto de tablas de destino y su estructura pueden cambiar entre versiones de ClickHouse.
Para que dichos cambios sean detectables, cada tabla TimeSeries almacena su versión en el SETTING version.
La versión se fija automáticamente en la consulta CREATE al crear la tabla —su valor es la última versión conocida por el servidor (actualmente 5)—,
persiste en los metadatos de la tabla y no puede modificarse mediante ALTER. Las tablas creadas antes de que se introdujera el SETTING se consideran de versión 0.
Lo normal es omitir el SETTING en la consulta CREATE TABLE: así la tabla obtiene la última versión.
Se acepta un valor explícito de version siempre que el servidor admita esa versión; en ese caso la tabla se define tal como lo hace esa versión (consulte Historial de versiones).
CREATE TABLE ... AS other_table no copia la versión de la otra tabla; consulte Crear una tabla AS una tabla existente.
Un servidor admite un rango de versiones, y la versión mínima puede variar según se trate de lectura con SELECT, de escritura con INSERT
o con el protocolo remote-write de Prometheus, o de evaluación de PromQL (las funciones de tabla prometheusQuery,
prometheusQueryRange
y timeSeriesSelector,
el dialecto promql y la API HTTP de consultas de Prometheus):
- Si la versión de una tabla
TimeSerieses demasiado antigua para PromQL, se rechazan las consultas PromQL sobre ella. La excepción sugiere volver a crear la tabla: cree una nueva tablaTimeSeries, copie los datos con una consultaINSERT ... SELECTy sustituya la tabla antigua por la nueva. - Si la versión es demasiado antigua para escribir en ella, se rechazan las consultas
INSERTy el protocolo remote-write de Prometheus, mientras que las consultasSELECTsiguen funcionando. - Si la versión es demasiado antigua para el servidor en general, se rechaza cualquier consulta sobre la tabla (excepto
SHOW CREATE TABLE,DETACHyDROP).
Historial de versiones
Funciones
Aquí tienes una lista de funciones que admiten una tablaTimeSeries como argumento: