Partições
PARTITION BY. Essa cláusula pode conter uma expressão SQL sobre qualquer coluna, e o resultado dessa expressão define para qual partição uma linha será enviada.
As partes de dados são associadas logicamente (por meio de um prefixo comum no nome da pasta) a cada partição no disco e podem ser consultadas isoladamente. No exemplo abaixo, o esquema padrão otel_logs particiona por dia usando a expressão toDate(Timestamp). À medida que as linhas são inseridas no ClickHouse, essa expressão é avaliada para cada linha, que é direcionada à partição resultante, caso ela exista (se a linha for a primeira de um dia, a partição será criada).
otel_logs esteja particionada por dia. Se for preenchida com o dataset estruturado de logs, ela conterá vários dias de dados:
otel_logs_archive, que usamos para armazenar dados mais antigos. Os dados podem ser movidos para essa tabela de forma eficiente por partição (isso é apenas uma alteração nos metadados).
INSERT INTO SELECT e a reescrita dos dados para a nova tabela de destino.
Movendo partiçõesMover partições entre tabelas exige o cumprimento de várias condições; entre elas, as tabelas devem ter a mesma estrutura, chave de partição, chave primária e índices e projeções. Observações detalhadas sobre como especificar partições em DDL
ALTER podem ser encontradas aqui.Esse recurso é aproveitado pelo TTL quando a configuração
ttl_only_drop_parts=1 é usada. Consulte Gerenciamento de dados com TTL para mais detalhes.Aplicações
- Arquiteturas em camadas - mover dados entre camadas de armazenamento (consulte Camadas de armazenamento), permitindo a construção de arquiteturas hot-cold.
- Exclusão eficiente - quando os dados atingirem um TTL especificado (consulte Gerenciamento de dados com TTL)
Desempenho de consultas
Gerenciamento de dados com TTL (time-to-live)
TTL no nível da tabela
ttl, por exemplo.
h e garantir que isso esteja alinhado ao período de particionamento. Por exemplo, se você faz o particionamento por dia, garanta que seja um múltiplo de dias, como 24h, 48h, 72h. Isso garantirá automaticamente que uma cláusula TTL seja adicionada à tabela, por exemplo, se ttl: 96h.
TTLs agendadosOs TTLs não são aplicados imediatamente, e sim de acordo com um agendamento, como observado acima. A configuração da tabela MergeTree
merge_with_ttl_timeout define o intervalo mínimo, em segundos, antes de repetir uma mesclagem com TTL de exclusão. O valor padrão é 14400 segundos (4 horas). Mas esse é apenas o intervalo mínimo; a mesclagem de TTL pode demorar mais para ser acionada. Se o valor for muito baixo, muitas mesclagens fora do agendamento serão executadas, o que pode consumir muitos recursos. A expiração de um TTL pode ser forçada com o comando ALTER TABLE my_table MATERIALIZE TTL.ttl_only_drop_parts=1 ** (aplicada pelo esquema padrão). Quando essa configuração está habilitada, o ClickHouse remove uma parte inteira quando todas as linhas nela tiverem expirado. Remover partes inteiras, em vez de limpar parcialmente linhas com TTL expirado (o que é feito por meio de mutações que consomem muitos recursos quando ttl_only_drop_parts=0), permite usar valores menores para merge_with_ttl_timeout e reduzir o impacto no desempenho do sistema. Se os dados estiverem particionados pela mesma unidade usada na expiração do TTL, por exemplo, dia, as partes naturalmente conterão apenas dados do intervalo definido. Isso garantirá que ttl_only_drop_parts=1 possa ser aplicado com eficiência.
TTL em nível de coluna
Body caso novos metadados dinâmicos sejam adicionados e ainda não tenham sido extraídos no momento da inserção, por exemplo, um novo rótulo do Kubernetes. Após um período, por exemplo 1 mês, pode ficar evidente que esses metadados adicionais não são úteis, reduzindo assim o valor de manter a coluna Body.
Abaixo, mostramos como a coluna Body pode ser removida após 30 dias.
Especificar um TTL em nível de coluna exige que os usuários definam seu próprio esquema. Isso não pode ser especificado no OTel collector.
Recompressão de dados
ZSTD(1) para dados de observabilidade, você pode experimentar diferentes algoritmos de compressão ou níveis mais altos de compressão, por exemplo, ZSTD(3). Além de poder especificar isso ao criar o esquema, a compressão pode ser configurada para mudar após um determinado período. Isso pode ser apropriado se um codec ou algoritmo de compressão melhorar a compressão, mas prejudicar o desempenho das consultas. Esse compromisso pode ser aceitável para dados mais antigos, que são consultados com menos frequência, mas não para dados recentes, que são usados com mais frequência em investigações.
Um exemplo disso é mostrado abaixo, em que comprimimos os dados usando ZSTD(3) após 4 dias, em vez de excluí-los.
Avalie o desempenhoRecomendamos que os usuários sempre avaliem o impacto no desempenho de inserção e de consulta de diferentes níveis e algoritmos de compressão. Por exemplo, codecs delta podem ser úteis na compressão de timestamps. No entanto, se fizerem parte da chave primária, o desempenho de filtragem pode ser prejudicado.
Camadas de armazenamento
Não se aplica ao ClickHouse CloudO ClickHouse Cloud usa uma única cópia dos dados com backend em S3, com caches SSD nos nós. Portanto, camadas de armazenamento no ClickHouse Cloud não são necessárias.
ALTER TABLE MOVE PARTITION, a movimentação de dados entre volumes também pode ser controlada usando TTLs. Um exemplo completo pode ser encontrado aqui.
Gerenciando alterações de esquema
Usar valores padrão
DEFAULT. O valor padrão especificado será usado se ele não for informado durante o INSERT.
As alterações no esquema podem ser feitas antes de modificar qualquer lógica de transformação da visão materializada ou configuração do OTel collector, para que essas novas colunas passem a ser enviadas.
Depois que o esquema for alterado, você poderá reconfigurar os OTel collectors. Supondo que os usuários estejam usando o processo recomendado descrito em “Extracting structure with SQL”, no qual os OTel collectors enviam seus dados para um Null table engine com uma visão materializada responsável por extrair o esquema de destino e enviar os resultados para uma tabela de destino para armazenamento, a visão pode ser modificada usando a sintaxe ALTER TABLE ... MODIFY QUERY. Suponha que temos a tabela de destino abaixo com sua visão materializada correspondente (semelhante à usada em “Extracting structure with SQL”) para extrair o esquema de destino dos logs estruturados do OTel:
Size de LogAttributes. Podemos adicioná-la ao nosso esquema com um ALTER TABLE, especificando o valor padrão:
size em LogAttributes (ele será 0 se ela não existir). Isso significa que as consultas que acessam essa coluna em linhas nas quais o valor não foi inserido precisam acessar o map e, portanto, serão mais lentas. Também poderíamos definir isso facilmente como uma constante, por exemplo, 0, reduzindo o custo das consultas subsequentes nessas linhas que não têm esse valor. Ao consultar essa tabela, vemos que o valor é preenchido a partir do map, conforme esperado:
ALTER TABLE, como mostrado abaixo:
Size preenchida durante a inserção.
Criar novas tabelas
ALTER TABLE MODIFY QUERY acima. Com essa abordagem, você pode versionar suas tabelas, por exemplo, otel_logs_v3.
Essa abordagem deixa os usuários com várias tabelas para consultar. Para consultar várias tabelas, você pode usar a função merge, que aceita patterns com curingas para o nome da tabela. Demonstramos isso abaixo consultando as versões v2 e v3 da tabela otel_logs:
merge e expor aos usuários finais uma tabela que combine várias tabelas, pode-se usar o motor de tabela Merge. Demonstramos isso abaixo:
EXCHANGE para tabelas. Por exemplo, para adicionar uma tabela v4, podemos criar uma nova tabela e trocá-la de forma atômica pela versão anterior.