Étape par étape : comment ClickHouse parallélise une requête d’agrégation
Répartition du travail entre les voies de traitement
n voies de traitement parallèles, qui acheminent et traitent les données bloc par bloc jusqu’au résultat final :
Le nombre de
n voies de traitement parallèles est contrôlé par le paramètre max_threads, qui correspond par défaut au nombre de cœurs (threads) d’un seul CPU mis à la disposition de ClickHouse sur le serveur. Dans l’exemple ci-dessus, nous supposons 4 cœurs.
Sur une machine avec 8 cœurs, le débit du traitement des requêtes doublerait approximativement (mais l’utilisation mémoire augmenterait également en conséquence), car davantage de voies traitent les données en parallèle :
Une répartition efficace des voies est essentielle pour maximiser l’utilisation du CPU et réduire le temps d’exécution total des requêtes.
Traitement des requêtes sur des tables shardées
Le serveur qui reçoit initialement la requête récupère tous les sous-résultats des shards et les combine pour produire le résultat global final. La répartition de la charge des requêtes entre les shards permet d’augmenter horizontalement le parallélisme, en particulier dans les environnements à fort débit.
ClickHouse Cloud utilise des répliques parallèles au lieu de shardsDans ClickHouse Cloud, ce même parallélisme est obtenu grâce aux parallel replicas, qui fonctionnent de manière similaire aux shards dans les clusters shared-nothing. Chaque réplique ClickHouse Cloud — un nœud de calcul sans état — traite une partie des données en parallèle et contribue au résultat final, comme le ferait un shard indépendant.
Surveillance du parallélisme des requêtes
- ① ClickHouse doit lire 3 609 granules (indiquées comme des marks dans les logs de trace) sur 3 plages de données.
- ② Avec 59 cœurs CPU, il répartit ce travail sur 59 flux de traitement parallèles — un par voie de traitement.
× 59 s’exécutent de manière concurrente sur des zones de données disjointes, réparties sur 59 voies de traitement parallèles. Cela reflète la valeur de max_threads et illustre comment chaque étape de la requête est parallélisée sur les cœurs du CPU.
L’interface web intégrée de ClickHouse (disponible sur l’endpoint /play) peut représenter le plan physique ci-dessus sous forme de visualisation graphique. Dans cet exemple, nous définissons max_threads sur 4 afin de conserver une visualisation compacte, avec seulement 4 voies de traitement parallèles affichées :
Remarque : lisez la visualisation de gauche à droite. Chaque ligne représente une voie de traitement parallèle qui fait circuler les blocs de données bloc par bloc, en appliquant des transformations telles que le filtrage, l’agrégation et les étapes finales de traitement. Dans cet exemple, vous pouvez voir quatre voies parallèles correspondant au paramètre max_threads = 4.
Équilibrage de charge entre les voies de traitement
Resize du plan physique ci-dessus repartitionnent et redistribuent les flux de blocs de données entre les voies de traitement afin d’en équilibrer l’utilisation. Ce rééquilibrage est particulièrement important lorsque les plages de données diffèrent par le nombre de lignes correspondant aux prédicats de la requête ; sinon, certaines voies risquent d’être surchargées tandis que d’autres restent inactives. En redistribuant le travail, les voies les plus rapides viennent en quelque sorte prêter main-forte aux plus lentes, ce qui optimise le temps d’exécution global de la requête.
Pourquoi max_threads n’est pas toujours respecté
n voies de traitement parallèles est contrôlé par le paramètre max_threads, qui correspond par défaut au nombre de cœurs de CPU disponibles pour ClickHouse sur le serveur :
max_threads peut ne pas être prise en compte en fonction de la quantité de données sélectionnée pour le traitement :
max_threads est défini sur 59, ClickHouse n’utilise que 30 flux parallèles pour parcourir les données.
Exécutons maintenant la requête :
max_threads, ClickHouse n’alloue des voies de traitement parallèles supplémentaires que s’il y a assez de données pour le justifier. Le « max » de max_threads désigne une limite supérieure, pas un nombre garanti de threads utilisés.
La notion de « quantité suffisante de données » est principalement déterminée par deux paramètres, qui définissent le nombre minimal de lignes (163 840 par défaut) et le nombre minimal d’octets (2 097 152 par défaut) que chaque voie de traitement doit traiter :
Pour les clusters shared-nothing :
Pour les clusters avec stockage partagé (par ex. ClickHouse Cloud) :
- merge_tree_min_rows_for_concurrent_read_for_remote_filesystem
- merge_tree_min_bytes_for_concurrent_read_for_remote_filesystem
max_threads.
Cela montre que, pour les requêtes portant sur de petits volumes de données, ClickHouse limitera volontairement la concurrence. N’utilisez les surcharges de paramètres que pour les tests, jamais en production, car elles peuvent entraîner une exécution inefficace ou une contention des ressources.
Points clés à retenir
- ClickHouse parallélise les requêtes à l’aide de voies de traitement liées à
max_threads. - Le nombre réel de voies dépend de la quantité de données sélectionnées pour le traitement.
- Utilisez
EXPLAIN PIPELINEet les logs de trace pour analyser l’utilisation des voies.
Où trouver plus d’informations
- Couche de traitement des requêtes – article VLDB 2024 (édition web) - Une présentation détaillée du modèle d’exécution interne de ClickHouse, notamment l’ordonnancement, l’exécution en pipeline et la conception des opérateurs.
- Explication des états d’agrégation partiels - Une analyse technique approfondie de la manière dont les états d’agrégation partiels permettent une exécution parallèle efficace sur plusieurs voies de traitement.
- Un tutoriel vidéo qui présente en détail toutes les étapes du traitement des requêtes dans ClickHouse :