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:
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
/merges, podemos usá-lo para visualizar todas as mesclagens de partes da nossa tabela de exemplo:
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
Cada thread de mesclagem executa um loop: ① Decide quais partes mesclar em seguida e carrega essas partes na memória. ② Mescla as partes na memória em uma parte maior. ③ Grava a parte mesclada no disco. Volta para ① 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
Mecânica da mesclagem
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 ② 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
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
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
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 com base nela.
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
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:
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.