Passer au contenu principal

Que sont les fusions de parts dans ClickHouse ?


ClickHouse est rapide non seulement pour les requêtes, mais aussi pour les insertions, grâce à sa couche de stockage, qui repose sur un principe proche de celui des arbres LSM : ① Les insertions (dans les tables de la famille du moteur MergeTree) créent des parts de données triées et immuables. ② Tout le traitement des données est pris en charge par des fusions de parts en arrière-plan. Les écritures de données sont ainsi légères et très efficaces. Pour contrôler le nombre de parts par table et mettre en œuvre le point ② ci-dessus, ClickHouse fusionne en continu (par partition) les petites parts en parts plus volumineuses en arrière-plan, jusqu’à ce qu’elles atteignent une taille compressée d’environ ~150 GB. Le schéma suivant illustre ce processus de fusion en arrière-plan :
Le merge level d’une part augmente de un à chaque fusion supplémentaire. Un niveau de 0 signifie que la part est nouvelle et n’a pas encore été fusionnée. Les parts fusionnées dans des parts plus grandes sont marquées comme inactives, puis définitivement supprimées après un délai configurable (8 minutes par défaut). Au fil du temps, cela crée un arbre de parts fusionnées. D’où le nom de table MergeTree.

Suivi des fusions

Dans l’exemple Que sont les parties de table, nous avons montré que ClickHouse suit toutes les parties de table dans la table système parts. Nous avons utilisé la requête suivante pour récupérer le niveau de fusion et le nombre de lignes stockées pour chaque partie active de la table d’exemple :
Le résultat de la requête précédemment documentée montre que la table d’exemple comportait quatre parts actives, chacune issue d’une unique fusion des parts initialement insérées :
En exécutant la requête montre désormais que les quatre parties ont fusionné en une seule partie finale (tant qu’aucune autre insertion n’est effectuée dans la table) :
Avec ClickHouse 24.10, un nouveau tableau de bord des fusions a été ajouté aux tableaux de bord de monitoring intégrés. Disponible aussi bien dans OSS que dans Cloud via le handler HTTP /merges, il permet de visualiser toutes les fusions de parts de notre table d’exemple :
L’enregistrement du tableau de bord ci-dessus montre l’ensemble du processus, des insertions de données initiales jusqu’à la fusion finale en une seule part : ① Nombre de parts actives. ② Fusions de parts, représentées visuellement par des boîtes (leur taille reflète la taille des parts). Amplification d’écriture.

Fusions concurrentes

Un serveur ClickHouse utilise plusieurs threads de fusion en arrière-plan pour exécuter des fusions de parts concurrentes :
Chaque thread de fusion exécute une boucle : ① Déterminer quelles parts fusionner ensuite, puis charger ces parts en mémoire. ② Fusionner les parts en mémoire en une part plus grande. ③ Écrire la part fusionnée sur disque. Revenir à ① Notez que l’augmentation du nombre de cœurs CPU et de la quantité de RAM permet d’augmenter le débit des fusions en arrière-plan.

Fusions économes en mémoire

ClickHouse ne charge pas nécessairement en mémoire, d’un seul coup, toutes les parts à fusionner, comme illustré dans l’exemple précédent. Selon plusieurs facteurs, et afin de réduire la consommation de mémoire (au détriment de la vitesse de fusion), la fusion verticale charge et fusionne les parts par fragments de blocs, au lieu de tout traiter en une seule fois.

Mécanisme des fusions

Le schéma ci-dessous illustre comment un seul thread de fusion en arrière-plan dans ClickHouse fusionne des parts (par défaut, sans fusion verticale) :
La fusion des parts s’effectue en plusieurs étapes : ① Décompression et chargement : les fichiers binaires de colonnes compressés des parts à fusionner sont décompressés et chargés en mémoire. ② Fusion : les données sont fusionnées dans des fichiers de colonnes plus volumineux. ③ Indexation : un nouvel index primaire clairsemé est généré pour les fichiers de colonnes fusionnés. ④ Compression et stockage : les nouveaux fichiers de colonnes et l’index sont compressés et enregistrés dans un nouveau répertoire représentant la part de données fusionnée. D’autres métadonnées des parts de données, telles que des index secondaires d’élagage de données, des statistiques de colonnes, des sommes de contrôle et des index min-max, sont également recréées à partir des fichiers de colonnes fusionnés. Nous avons omis ces détails par souci de simplicité. Le mécanisme de l’étape ② dépend du moteur MergeTree utilisé, car les différents moteurs ne fusionnent pas les données de la même manière. Par exemple, les lignes peuvent être agrégées ou remplacées si elles sont obsolètes. Comme indiqué plus haut, cette approche déporte tout le traitement des données vers les fusions en arrière-plan, ce qui permet des insertions ultra-rapides en conservant des opérations d’écriture légères et efficaces. Nous allons maintenant présenter brièvement le mécanisme de fusion de certains moteurs de la famille MergeTree.

Fusions standards

Le diagramme ci-dessous illustre comment les parts d’une table MergeTree standard sont fusionnées :
L’instruction DDL du diagramme ci-dessus crée une table MergeTree avec une clé de tri (town, street), ce qui signifie que les données sur disque sont triées selon ces colonnes et qu’un index primaire clairsemé est généré en conséquence. Les colonnes de la table, ① décompressées et prétriées, sont ② fusionnées tout en préservant l’ordre de tri global de la table défini par sa clé de tri, ③ un nouvel index primaire clairsemé est généré, et ④ les fichiers de colonnes fusionnés et l’index sont compressés puis stockés sur disque sous la forme d’une nouvelle part de données.

Fusions de remplacement

Les fusions de parts dans une table ReplacingMergeTree fonctionnent de manière similaire aux fusions standard, mais seule la version la plus récente de chaque ligne est conservée, les versions plus anciennes étant supprimées :
L’instruction DDL dans le schéma ci-dessus crée une table ReplacingMergeTree avec une clé de tri (town, street, id), ce qui signifie que les données sur disque sont triées selon ces colonnes, avec un index primaire clairsemé généré en conséquence. L’étape de fusion ② fonctionne de manière similaire à celle d’une table MergeTree standard, en combinant des colonnes décompressées et prétriées tout en préservant l’ordre de tri global. Cependant, ReplacingMergeTree supprime les lignes dupliquées ayant la même clé de tri, en ne conservant que la ligne la plus récente selon l’horodatage de création de la part qui la contient.

Fusions par sommation

Les données numériques sont automatiquement agrégées lors des fusions de parties d’une table SummingMergeTree :
L’instruction DDL du schéma ci-dessus définit une table SummingMergeTree avec town comme clé de tri, ce qui signifie que les données sur disque sont triées selon cette colonne et qu’un index primaire clairsemé est créé en conséquence. À l’étape ② de la fusion, ClickHouse remplace toutes les lignes ayant la même clé de tri par une seule ligne, en additionnant les valeurs des colonnes numériques.

Fusions avec agrégation

L’exemple de table SummingMergeTree ci-dessus est une variante spécialisée de la table AggregatingMergeTree, qui permet une transformation automatique incrémentielle des données en appliquant l’une des 90+ fonctions d’agrégation lors des fusions de parts :
L’instruction DDL du schéma ci-dessus crée une table AggregatingMergeTree avec town comme clé de tri, ce qui garantit que les données sont ordonnées selon cette colonne sur disque et qu’un index primaire clairsemé correspondant est généré. Lors de l’étape de fusion ②, ClickHouse remplace toutes les lignes ayant la même clé de tri par une seule ligne stockant des états d’agrégation partiels (par ex. un sum et un count pour avg()). Ces états garantissent des résultats exacts grâce aux fusions incrémentielles en arrière-plan.
Dernière modification le 29 juin 2026