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
/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
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
Mécanisme des fusions
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
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
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
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
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.