¿Qué son las fusiones de partes en ClickHouse?
ClickHouse es rápido no solo para las consultas, sino también para las inserciones, gracias a su capa de almacenamiento, que funciona de forma similar a los árboles LSM: ① Las inserciones (en tablas de la familia del motor MergeTree) crean partes de datos ordenadas e inmutables. ② Todo el procesamiento de los datos se delega a fusiones de partes en segundo plano. Esto hace que las escrituras de datos sean ligeras y muy eficientes. Para controlar el número de partes por tabla e implementar el punto ② anterior, ClickHouse fusiona continuamente (por partición) las partes más pequeñas en otras más grandes en segundo plano hasta que alcanzan un tamaño comprimido aproximado de ~150 GB. El siguiente diagrama ilustra este proceso de fusión en segundo plano:
El
nivel de fusión de una parte aumenta en uno con cada fusión adicional. Un nivel de 0 significa que la parte es nueva y aún no se ha fusionado. Las partes que se fusionaron en otras más grandes se marcan como inactivas y, por último, se eliminan tras un tiempo configurable (8 minutos de forma predeterminada). Con el tiempo, esto crea un árbol de partes fusionadas. De ahí el nombre de la tabla merge tree.
Monitorización de las fusiones
handler HTTP /merges, podemos usarlo para visualizar todas las fusiones de partes de nuestra tabla de ejemplo:
La grabación del dashboard anterior muestra todo el proceso, desde las inserciones iniciales de datos hasta la fusión final en una sola parte: ① Número de partes activas. ② Fusiones de partes, representadas visualmente con cuadros (su tamaño refleja el tamaño de la parte). ③ Amplificación de escritura.
Fusiones concurrentes
Cada hilo de fusión ejecuta un bucle:
1
Cargar partes en memoria
Decide qué partes fusionar a continuación y carga esas partes en memoria.
2
Fusionar partes
Fusiona las partes en memoria en una parte más grande.
3
Escribir en disco
Escribe la parte fusionada en disco y, a continuación, vuelve al paso 1.
Fusiones con uso de memoria optimizado
Mecánica de las fusiones
La fusión de partes se realiza en varios pasos:
1
Descompresión y carga
Los archivos binarios comprimidos de columnas de las partes que se van a fusionar se descomprimen y se cargan en memoria.
2
Fusión
Los datos se fusionan en archivos de columnas más grandes.
3
Indexación
Se genera un nuevo índice primario disperso para los archivos de columnas fusionados.
4
Compresión y almacenamiento
Los nuevos archivos de columnas y el índice se comprimen y se guardan en un nuevo directorio que representa la parte de datos fusionada.
Fusiones estándar
La sentencia DDL del diagrama anterior crea una tabla
MergeTree con una clave de ordenación (town, street), lo que significa que los datos en disco se ordenan según estas columnas y que, en consecuencia, se genera un índice primario disperso.
Las columnas de la tabla ① descomprimidas y preordenadas se ② fusionan manteniendo el orden global de clasificación de la tabla definido por su clave de ordenación, ③ se genera un nuevo índice primario disperso y ④ los archivos de columna fusionados y el índice se comprimen y se almacenan como una nueva parte de datos en disco.
Fusiones con reemplazo
La sentencia DDL del diagrama anterior crea una tabla
ReplacingMergeTree con una clave de ordenación (town, street, id), lo que significa que los datos en disco se ordenan según esas columnas y que, en consecuencia, se genera un índice primario disperso.
La ② fusión funciona de forma similar a la de una tabla MergeTree estándar: combina columnas descomprimidas y preordenadas mientras mantiene el orden global de ordenación.
Sin embargo, ReplacingMergeTree elimina las filas duplicadas con la misma clave de ordenación y conserva solo la fila más reciente, según la marca temporal de creación de la parte que la contiene.
Fusiones con suma
La sentencia DDL del diagrama anterior define una tabla
SummingMergeTree con town como clave de ordenación, lo que significa que los datos en disco se ordenan según esta columna y que, en consecuencia, se crea un índice primario disperso.
En el paso ② de fusión, ClickHouse reemplaza todas las filas con la misma clave de ordenación por una sola fila, sumando los valores de las columnas numéricas.
Fusiones con agregación
SummingMergeTree es una variante especializada de la tabla AggregatingMergeTree, que permite la transformación automática e incremental de datos al aplicar cualquiera de las 90+ funciones de agregación durante las fusiones de partes:
La sentencia DDL del diagrama anterior crea una tabla
AggregatingMergeTree con town como clave de ordenación, lo que garantiza que los datos se ordenen por esta columna en disco y que se genere el índice primario disperso correspondiente.
Durante la fusión ②, ClickHouse sustituye todas las filas con la misma clave de ordenación por una única fila que almacena estados parciales de agregación (por ejemplo, un sum y un count para avg()). Estos estados garantizan resultados precisos mediante fusiones incrementales en segundo plano.