Este é um recurso em visualização privada que pode mudar de formas incompatíveis com versões anteriores em lançamentos futuros.
Habilite o uso do motor de tabela TimeSeries
com a configuração
enable_time_series_table.
Execute o comando set enable_time_series_table = 1.O motor de tabela
TimeSeries está disponível no ClickHouse Cloud como um recurso em visualização privada.
Os serviços que participam da visualização privada já possuem a configuração
enable_time_series_table definida. Outros serviços do ClickHouse Cloud
não têm essa configuração, e você não pode habilitar o motor por conta própria em
um serviço desse tipo.Sintaxe
A palavra-chave
SAMPLES tem um alias DATA, e a palavra-chave METRIC FAMILIES tem um alias METRICS, ambos mantidos por compatibilidade com versões anteriores.
A definição de uma tabela de uma version anterior à 4 é gravada com METRICS, para que um servidor mais antigo possa lê-la.Uso
É mais fácil começar com tudo configurado com os valores padrão (é permitido criar uma tabelaTimeSeries sem especificar uma lista de colunas):
Colunas externas
As colunas de uma tabela TimeSeries são geradas automaticamente. São colunas externas: não armazenam dados, apenas fornecem a interface para SELECT/INSERT. Os dados reais são armazenados em tabelas de destino. Aqui está a lista das colunas externas:
Exemplo:
metric_name fique vazio na inserção; isso significa que o nome da métrica é especificado em tags, em __name__, por exemplo:
metric_family, type, unit e help:
Especificando colunas externas
A coluna externasamples pode ser listada explicitamente em uma instrução CREATE TABLE para substituir seu tipo padrão Array(Tuple(DateTime64(3), Float64)) (seu nome antigo, time_series, também é aceito). O ClickHouse extrai, da tupla, os tipos de timestamp e do valor escalar e os propaga para a tabela samples:
INNER COLUMNS de samples, os tipos das colunas de timestamp e valor:
CREATE TABLE, os tipos declarados deverão coincidir.
Tabelas de destino
Uma tabelaTimeSeries não armazena dados próprios; tudo é armazenado em suas tabelas de destino.
Isso é semelhante ao funcionamento de uma visão materializada,
com a diferença de que uma visão materializada tem uma tabela de destino,
enquanto uma tabela TimeSeries tem três tabelas de destino obrigatórias chamadas samples, tags e metric families,
e uma tabela de destino opcional amostras recentes, que vem habilitada por padrão
(consulte a configuração recent_samples_ttl_seconds).
As tabelas de destino podem ser especificadas explicitamente na consulta CREATE TABLE
ou o motor de tabela TimeSeries pode gerar automaticamente tabelas de destino internas.
As linhas inseridas em uma tabela TimeSeries são transformadas, divididas em blocos e inseridas nessas tabelas de destino.
As tabelas de destino são as seguintes:
Tabela samples
A tabela samples contém séries temporais associadas a um identificador. A tabela samples deve ter as seguintes colunas:
As colunas que o motor cria por conta própria recebem codecs de compressão de séries temporais:
timestamp CODEC(Delta, T64, ZSTD(3)) e value CODEC(ALP, ZSTD(3)). Timestamps quase monotônicos mal
são comprimidos por codecs genéricos e podem, caso contrário, dominar o tamanho em disco da tabela samples.
O motor habilita ALP para suas tabelas internas samples e amostras recentes sem exigir que enable_alp_codec seja definido.
Consulte também Ajustando os tipos das colunas.
Tabela de amostras recentes
A tabela de amostras recentes é opcional e está habilitada por padrão (consulte a configuração recent_samples_ttl_seconds; defini-la como zero desabilita a tabela). Ela contém uma cópia das amostras mais recentes que o TTL definido por essa configuração e deve ter as mesmas colunas que a tabela samples. A colunatimestamp gerada usa CODEC(Delta, T64, ZSTD(3)),
e a coluna value gerada usa CODEC(ALP, ZSTD(3)).
Toda amostra inserida é gravada tanto na tabela samples quanto na tabela de amostras recentes.
As consultas cujo intervalo de tempo se encaixa na janela do TTL leem da tabela de amostras recentes em vez da tabela samples principal,
já que ela é muito menor (esse comportamento pode ser desabilitado com a configuração de nível de consulta time_series_prefer_recent_samples_table).
O TTL da tabela interna de amostras recentes é sempre derivado da configuração recent_samples_ttl_seconds.
Tabela de tags
A tabela tags contém identificadores calculados para cada combinação de nome de métrica e tags. A tabela tags deve ter as colunas:
Novas tabelas internas de tags da versão 5 e posteriores com um motor da família
MergeTree têm um índice de texto invertido em tags:
INDEX tags_idx tags TYPE text(tokenizer = 'keyValuePairs'). Ele acelera correspondências exatas de rótulos, como
{job="api"} em PromQL, consultando a chave e o valor em conjunto. Comparações com uma string vazia também
correspondem a rótulos ausentes e não usam esse índice.
Índices explícitos declarados em TAGS INNER COLUMNS substituem o índice padrão. As tabelas existentes e as
tabelas de tags externas mantêm seus índices; adicione e materialize o índice na tabela de destino das tags para habilitá-lo.
Tabela de famílias de métricas
A tabela metric families contém algumas informações sobre as famílias de métricas coletadas, os tipos dessas famílias de métricas e suas descrições. Uma família de métricas é um grupo de métricas com o mesmo nome (a tag__name__) e o mesmo tipo; por exemplo, um histograma é uma família de métricas composta por várias métricas.
A tabela metric families deve conter as colunas:
Criação
Existem várias maneiras de criar uma tabela com o motor de tabelaTimeSeries.
A instrução mais simples
SHOW CREATE TABLE my_table):
INNER COLUMNS. A configuração recent_samples_ttl_seconds foi gravada na cláusula SETTINGS
com seu valor padrão: essa configuração define o TTL da tabela de amostras recentes, de modo que seu valor efetivo é fixado na criação.
Além disso, a versão de schema mais recente foi fixada na configuração version (consulte Versionamento de schema).
As tabelas de destino internas têm nomes 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
e cada tabela de destino tem seu próprio conjunto de colunas:
Criar uma tabela AS a partir de uma tabela existente
A instruçãoCREATE TABLE new_table AS existing_table cria uma tabela TimeSeries configurada como existing_table,
que deve ser uma tabela TimeSeries. Os destinos externos de existing_table não são copiados: a própria instrução deve declarar
esses destinos.
A instrução copia de existing_table:
- a cláusula
SETTINGS, excetoversion: a nova tabela sempre recebe a versão mais recente. As configurações especificadas na instrução são mescladas às copiadas pelo nome; portanto, uma configuração especificada prevalece sobre a copiada, ename = DEFAULTredefine uma configuração copiada para o valor padrão; - as cláusulas
INNER COLUMNSeINNER ENGINEde cada tabela interna. Colunas personalizadas (por exemplo, colunas extras ou colunas com um codec ou uma expressão DEFAULT) e partes personalizadas do motor (por exemplo, um motor com argumentos, uma chave de ordenação personalizada ou uma configuração do motor) são mantidas; as demais colunas e partes do motor são ajustadas às configurações da nova tabela para que, por exemplo,tags_to_columns,aggregate_min_time_and_max_timeoutags_index_granularityespecificadas na instrução tenham efeito.
id, de timestamp e de valor, bem como o tipo de replicação dos motores internos (MergeTree,
ReplicatedMergeTree ou SharedMergeTree), também são obtidos de existing_table, a menos que a própria instrução os declare.
A lista de colunas externas é regenerada, não copiada.
Uma tabela criada por uma versão mais antiga do ClickHouse pode ser usada como existing_table: a nova tabela recebe a
estrutura atual, por exemplo, o tipo id atual e a expressão padrão de identificador.
Ajustando os tipos das colunas
Você pode ajustar os tipos das colunas nas tabelas de destino internas usando a cláusulaINNER COLUMNS. Por exemplo, para armazenar timestamps em microssegundos e valores como Float32, use:
A coluna id
A coluna id contém identificadores; cada identificador é calculado com base em uma combinação de nome de métrica e tags.
O tipo e a expressão DEFAULT usados para gerar identificadores podem ser personalizados por meio da cláusula TAGS INNER COLUMNS:
id pode ser de qualquer tipo comparável que não seja Nullable. Os tipos de id declarados nas tabelas internas samples e tags devem corresponder.
Se nenhuma expressão DEFAULT for fornecida para a coluna id e a configuração id_generator não estiver definida, ClickHouse escolherá a expressão DEFAULT automaticamente com base no tipo de id, mas apenas se o tipo de id for um dos seguintes: UUID, UInt64, UInt128, FixedString(16), os mesmos tipos encapsulados em LowCardinality ou uma tupla de dois desses tipos. Para essa tupla, a expressão escolhida automaticamente calcula um hash do nome de métrica no primeiro componente e um hash de todas as tags no segundo componente.
Um tipo de identificador LowCardinality, por exemplo Tuple(UInt64, LowCardinality(UUID)), mantém os identificadores codificados por dicionário: a tabela samples armazena pequenos dicionários por bloco com dictionary indexes em vez de repetir o identificador completo em cada linha, o que reduz a quantidade de dados lidos pelas consultas.
A configuração id_generator oferece a mesma personalização sem usar a cláusula INNER COLUMNS:
id, mesmo que o DEFAULT da coluna contenha uma expressão diferente.
O tipo da coluna id também pode ser especificado na configuração id_type em vez da cláusula INNER COLUMNS:
id_generator está definida, a configuração id_type é registrada automaticamente no momento do CREATE, de modo que a definição preserva o tipo para o qual a expressão foi escrita.
A coluna tags
A coluna tags contém todas as tags de uma série temporal, incluindo a tag __name__ com o nome de uma métrica.
A configuração tags_to_columns permite especificar que uma tag específica também deve ser armazenada em uma coluna separada
além do map dentro da coluna tags:
instance e job à tabela de destino interna de tags.
Os valores das tags instance e job serão armazenados tanto nessas colunas quanto na coluna tags.
Nas tabelas criadas por versões mais antigas do ClickHouse, a coluna
tags contém apenas as tags sem colunas
dedicadas e sem o nome da métrica, e a coluna all_tags é uma coluna efêmera preenchida na inserção
com todas as tags, exceto o nome da métrica.Motores de tabela das tabelas de destino internas
Por padrão, as tabelas de destino internas usam os seguintes motores de tabela:- a tabela samples usa MergeTree;
- a tabela amostras recentes usa MergeTree particionada em buckets de 5 horas (consulte a configuração recent_samples_partition_by) com um
TTLderivado da configuração recent_samples_ttl_seconds e comttl_only_drop_partshabilitado, de modo que as partes expiradas são removidas por inteiro; - a tabela tags usa AggregatingMergeTree porque os mesmos dados costumam ser inseridos várias vezes nessa tabela, então precisamos de uma forma
de remover duplicatas, além de ser necessário fazer agregação para as colunas
min_timeemax_time; - a tabela famílias de métricas usa ReplacingMergeTree porque os mesmos dados costumam ser inseridos várias vezes nessa tabela, então precisamos de uma forma de remover duplicatas.
default_table_engine:
com default_table_engine = ReplicatedMergeTree ou SharedMergeTree, as tabelas internas usam os motores
Replicated ou Shared correspondentes. Com default_table_engine = None (ou qualquer outro valor), os motores das tabelas internas
devem ser especificados explicitamente.
Todas as tabelas internas devem ter o mesmo tipo de replicação: se uma delas for replicada (ou compartilhada), as demais tabelas
internas também devem ser replicadas (ou compartilhadas); caso contrário, seus conteúdos divergiriam entre as réplicas. Por exemplo,
declarar SAMPLES INNER ENGINE = ReplicatedMergeTree(...) exige que os demais motores internos também sejam replicados —
seja declarados explicitamente ou gerados com default_table_engine = ReplicatedMergeTree.
Outros motores de tabela também podem ser usados nas tabelas de destino internas, caso isso seja especificado:
tags) fora de sua chave de ordenação,
o que AggregatingMergeTree rejeita por padrão (consulte allow_dimensions_outside_sorting_key).
Isso é seguro aqui porque essas colunas dependem funcionalmente de id, que faz parte da chave de ordenação, portanto todas as
linhas que uma mesclagem em segundo plano combina compartilham os mesmos valores. Quando a tabela interna de tags é gerada ou seu
motor é especificado inline, como acima, TimeSeries define allow_dimensions_outside_sorting_key = 1 nela automaticamente;
para uma tabela externa de tags com agregação criada manualmente, você deve definir isso por conta própria.
Tabelas de destino externas
É possível fazer com que uma tabelaTimeSeries use uma tabela criada manualmente:
RECENT SAMPLES my_recent_samples_table).
Essa tabela deve ter as mesmas colunas de uma tabela samples externa e deve reter pelo menos
recent_samples_ttl_seconds segundos de dados, o que é responsabilidade do usuário.
Os tipos de coluna das tabelas externas (id, timestamp, value e os <tag_value_column> listados em tags_to_columns) devem corresponder aos que a tabela TimeSeries geraria internamente (consulte Tabela samples, Tabela de Tags e Tabela de famílias de métricas para as restrições de tipo). Incompatibilidades de tipo são informadas no momento do CREATE.
O tipo da coluna id de uma tabela de tags externa e a expressão que gera os identificadores são registrados nas configurações id_type e id_generator no momento do CREATE (a partir da versão 2), de modo que a definição da tabela TimeSeries os mantém: por exemplo, CREATE TABLE ... AS my_table lê o tipo de id a partir da definição de my_table sem ler suas tabelas de destino externas. Se a configuração id_generator não for especificada, ela é definida como o DEFAULT declarado na coluna id da tabela externa (se houver) ou, caso contrário, como o gerador canônico derivado do tipo de id. A expressão registrada é usada para gerar o id mesmo que o DEFAULT da tabela externa mude posteriormente — consulte A coluna id para mais detalhes.
Alterando configurações
Duas configurações podem ser alteradas apósCREATE:
id_generatorfilter_by_min_time_and_max_time
id_generator quando já existem dados na tabela de tags pode gerar IDs diferentes para a mesma combinação de métrica+tag — as linhas antigas mantêm seus IDs antigos, e as linhas novas usam o novo gerador.
As outras configurações não podem ser alteradas com ALTER ... MODIFY SETTING: a maioria delas é incorporada ao esquema das tabelas internas no momento do CREATE,
e a configuração version é fixada automaticamente no momento do CREATE e identifica o próprio esquema (consulte Versionamento de schema).
Configurações
Aqui está uma lista de configurações que podem ser especificadas ao definir uma tabelaTimeSeries:
Versionamento de schema
O motor de tabelaTimeSeries e a camada de execução de PromQL estão em desenvolvimento ativo:
o conjunto de tabelas de destino e sua estrutura podem mudar entre versões do ClickHouse.
Para tornar essas mudanças detectáveis, cada tabela TimeSeries armazena sua versão na configuração version.
A versão é fixada automaticamente na consulta CREATE no momento da criação da tabela — seu valor é a versão mais recente conhecida pelo servidor (atualmente 5) —,
persiste nos metadados da tabela e não pode ser alterada por ALTER. Tabelas criadas antes da introdução dessa configuração são consideradas como versão 0.
Normalmente, basta omitir a configuração na consulta CREATE TABLE — assim a tabela recebe a versão mais recente.
Um version explícito é aceito se o servidor der suporte a essa versão; nesse caso, a tabela é definida da forma como aquela versão a define (consulte Histórico de versões).
CREATE TABLE ... AS other_table não copia a versão da outra tabela; consulte Criar uma tabela AS a partir de uma tabela existente.
Um servidor dá suporte a um intervalo de versões, e a versão mínima pode variar conforme a operação: leitura com SELECT, gravação com INSERT
ou com o protocolo remote-write do Prometheus, e avaliação de PromQL (as funções de tabela prometheusQuery,
prometheusQueryRange
e timeSeriesSelector,
o dialect promql e a API HTTP de consulta do Prometheus):
- Se a versão de uma tabela
TimeSeriesfor antiga demais para PromQL, as consultas PromQL sobre ela são rejeitadas. A exceção sugere recriar a tabela: crie uma nova tabelaTimeSeries, copie os dados com uma consultaINSERT ... SELECTe substitua a tabela antiga pela nova. - Se a versão for antiga demais para gravação, as consultas
INSERTe o protocolo remote-write do Prometheus são rejeitados, enquanto as consultasSELECTcontinuam funcionando. - Se a versão for antiga demais para o servidor como um todo, toda consulta sobre a tabela (exceto
SHOW CREATE TABLE,DETACHeDROP) é rejeitada.
Histórico de versões
Funções
Aqui está uma lista de funções que aceitam uma tabelaTimeSeries como argumento: