Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Mesclagem de partes

O que são mesclagens de partes no ClickHouse?


O ClickHouse é rápido não apenas para consultas, mas também para inserções, graças à sua camada de armazenamento, que funciona de forma semelhante a árvores LSM:

① Inserções (em tabelas da família de motores MergeTree) criam partes de dados ordenadas e imutáveis.

② Todo o processamento de dados é transferido para mesclagens de partes em segundo plano.

Isso torna as gravações de dados leves e altamente eficientes.

Para controlar o número de partes por tabela e implementar o item ② acima, o ClickHouse mescla continuamente (por partição) partes menores em partes maiores em segundo plano, até que atinjam um tamanho comprimido de aproximadamente ~150 GB.

O diagrama a seguir ilustra esse processo de mesclagem em segundo plano:

mesclagem de partes

O nível de mesclagem de uma parte é incrementado em um a cada nova mesclagem. Um nível de 0 significa que a parte é nova e ainda não foi mesclada. As partes que foram mescladas em partes maiores são marcadas como inativas e, por fim, excluídas após um período configurável (8 minutos por padrão). Com o tempo, isso cria uma árvore de partes mescladas. Daí o nome da tabela MergeTree.

Monitoramento de mesclagens

No exemplo o que são partes de tabela, mostramos que o ClickHouse acompanha todas as partes de tabela na tabela de sistema parts. Usamos a seguinte consulta para obter o nível de mesclagem e o número de linhas armazenadas em cada parte ativa da tabela de exemplo:

SELECT
    name,
    level,
    rows
FROM system.parts
WHERE (database = 'uk') AND (`table` = 'uk_price_paid_simple') AND active
ORDER BY name ASC;

O resultado da consulta documentada anteriormente mostra que a tabela de exemplo tinha quatro partes ativas, cada uma criada a partir de uma única mesclagem das partes inseridas inicialmente:

   ┌─name────────┬─level─┬────rows─┐
1. │ all_0_5_1   │     1 │ 6368414 │
2. │ all_12_17_1 │     1 │ 6442494 │
3. │ all_18_23_1 │     1 │ 5977762 │
4. │ all_6_11_1  │     1 │ 6459763 │
   └─────────────┴───────┴─────────┘

Executando a consulta, agora é possível ver que as quatro partes já foram mescladas em uma única parte final (desde que não haja novos inserts na tabela):

   ┌─name───────┬─level─┬─────rows─┐
1. │ all_0_23_2 │     2 │ 25248433 │
   └────────────┴───────┴──────────┘

No ClickHouse 24.10, um novo dashboard de mesclagens foi adicionado aos dashboards de monitoramento integrados. Disponível tanto no OSS quanto no Cloud por meio do manipulador HTTP /merges, podemos usá-lo para visualizar todas as mesclagens de partes da nossa tabela de exemplo:

mesclagem de partes

A gravação do dashboard acima mostra todo o processo, desde as inserções iniciais de dados até a mesclagem final em uma única parte:

① Número de partes ativas.

② Mesclagens de partes, representadas visualmente por caixas (o tamanho reflete o tamanho da parte).

Amplificação de gravação.

Mesclagens concorrentes

Um único servidor ClickHouse usa várias threads de mesclagem em segundo plano para executar mesclagens de partes simultaneamente:

MESCLAGENS DE PARTES

Cada thread de mesclagem executa um loop:

Carregar partes na memória

Decide quais partes mesclar em seguida e carrega essas partes na memória.

Mesclar partes

Mescla as partes na memória em uma parte maior.

Gravar no disco

Grava a parte mesclada no disco e retorna ao passo 1.

Observe que aumentar o número de núcleos de CPU e a quantidade de RAM permite aumentar a taxa de transferência das mesclagens em segundo plano.

Mesclagens com otimização de memória

O ClickHouse não necessariamente carrega na memória, de uma só vez, todas as partes a serem mescladas, como ilustrado no exemplo anterior. Dependendo de vários fatores, e para reduzir o consumo de memória (em troca de velocidade de mesclagem), a chamada mesclagem vertical carrega e mescla as partes em fragmentos de blocos, em vez de fazer isso de uma só vez.

Mecânica da mesclagem

O diagrama abaixo ilustra como uma única thread de mesclagem em segundo plano no ClickHouse mescla partes (por padrão, sem mesclagem vertical):

mesclagem de partes

A mesclagem de partes é realizada em várias etapas:

Descompressão e carregamento

Os arquivos binários comprimidos das colunas das partes a serem mescladas são descomprimidos e carregados na memória.

Mesclagem

Os dados são mesclados em arquivos de coluna maiores.

Indexação

Um novo índice primário esparso é gerado para os arquivos de coluna mesclados.

Compressão e armazenamento

Os novos arquivos de coluna e o índice são comprimidos e salvos em um novo diretório que representa a parte de dados mesclada.

Metadados adicionais nas partes de dados, como índices secundários de data skipping, estatísticas de coluna, checksum e índices min-max, também são recriados com base nos arquivos de coluna mesclados. Omitimos esses detalhes para simplificar.

A mecânica da etapa de mesclagem depende do motor MergeTree específico usado, pois motores diferentes tratam a mesclagem de maneiras diferentes. Por exemplo, as linhas podem ser agregadas ou substituídas se estiverem desatualizadas. Como mencionado anteriormente, essa abordagem transfere todo o processamento de dados para as mesclagens em segundo plano, permitindo inserções extremamente rápidas ao manter as operações de gravação leves e eficientes.

Em seguida, apresentaremos brevemente a mecânica de mesclagem de motores específicos da família MergeTree.

Mesclagens padrão

O diagrama abaixo ilustra como as partes em uma tabela MergeTree padrão são mescladas:

MESCLAGEM DE PARTES

A instrução DDL no diagrama acima cria uma tabela MergeTree com uma chave de ordenação (town, street), o que significa que os dados em disco são ordenados por essas colunas e que um índice primário esparso é gerado com base nelas.

As colunas da tabela ① descomprimidas e pré-ordenadas são ② mescladas, preservando a ordem global de classificação da tabela definida pela chave de ordenação; ③ um novo índice primário esparso é gerado; e ④ os arquivos de coluna mesclados e o índice são comprimidos e armazenados como uma nova parte de dados em disco.

Mesclagens com substituição

As mesclagens de partes em uma tabela ReplacingMergeTree funcionam de forma semelhante às mesclagens padrão, mas apenas a versão mais recente de cada linha é mantida, enquanto as versões mais antigas são descartadas:

mesclagem de partes

A instrução DDL no diagrama acima cria uma tabela ReplacingMergeTree com uma chave de ordenação (town, street, id), o que significa que os dados em disco são ordenados por essas colunas, com um índice primário esparso correspondente sendo gerado.

A mesclagem em ② funciona de forma semelhante à de uma tabela MergeTree padrão, combinando colunas descomprimidas e pré-ordenadas, enquanto preserva a ordem global de ordenação.

No entanto, a ReplacingMergeTree remove linhas duplicadas com a mesma chave de ordenação, mantendo apenas a linha mais recente com base no timestamp de criação da parte que a contém.


Mesclagens por soma

Os dados numéricos são agregados automaticamente durante as mesclagens de partes de uma tabela SummingMergeTree:

mesclagem de partes

A instrução DDL no diagrama acima define uma tabela SummingMergeTree com town como chave de ordenação, o que significa que os dados em disco são ordenados por essa coluna e um índice primário esparso é criado de acordo.

Na etapa de mesclagem ②, o ClickHouse substitui todas as linhas com a mesma chave de ordenação por uma única linha, somando os valores das colunas numéricas.

Mesclagens com agregação

O exemplo de tabela SummingMergeTree acima é uma variante especializada da tabela AggregatingMergeTree, permitindo a transformação automática e incremental de dados ao aplicar qualquer uma das mais de 90 funções de agregação durante as mesclagens de partes:

MESCLAGENS DE PARTES

A instrução DDL no diagrama acima cria uma tabela AggregatingMergeTree com town como chave de ordenação, garantindo que os dados sejam ordenados por essa coluna em disco e que um índice primário esparso correspondente seja gerado.

Durante a mesclagem ②, o ClickHouse substitui todas as linhas com a mesma chave de ordenação por uma única linha que armazena estados de agregação parciais (por exemplo, um sum e um count para avg()). Esses estados garantem resultados precisos por meio de mesclagens incrementais em segundo plano.

Navigation