Pourquoi utiliser ClickHouse Cloud plutôt que BigQuery ?
Chargement de données de BigQuery vers ClickHouse Cloud
Jeu de données
post, vote, user, comment et badge apparus sur Stack Overflow entre 2008 et avril 2024. Le schéma BigQuery de ces données est présenté ci-dessous :
Pour les utilisateurs qui souhaitent charger ce jeu de données dans une instance BigQuery afin de tester les étapes de migration, nous fournissons les données de ces tables au format Parquet dans un GCS bucket, et les commandes DDL pour créer et charger les tables dans BigQuery sont disponibles ici.
Migration des données
- Chargement initial en masse avec mises à jour périodiques - Un jeu de données initial doit être migré, puis mis à jour à intervalles réguliers, par exemple chaque jour. Les mises à jour sont ici gérées en renvoyant les lignes modifiées, identifiées à l’aide d’une colonne pouvant servir à la comparaison (par exemple, une date). Les suppressions sont gérées par un rechargement périodique complet du jeu de données.
- Réplication en temps réel ou CDC - Un jeu de données initial doit être migré. Les modifications apportées à ce jeu de données doivent être répercutées dans ClickHouse en quasi temps réel, avec un délai de quelques secondes tout au plus. Il s’agit en pratique d’un processus de capture des changements de données (CDC), dans lequel les tables BigQuery doivent être synchronisées avec ClickHouse, c’est-à-dire que les inserts, mises à jour et suppressions dans la table BigQuery doivent être appliqués à une table équivalente dans ClickHouse.
Chargement en masse via Google Cloud Storage (GCS)
- Exportez les 7 tables vers GCS. Les commandes correspondantes sont disponibles ici.
-
Importez les données dans ClickHouse Cloud. Pour cela, nous pouvons utiliser la fonction de table gcs. Les requêtes DDL et d’importation sont disponibles ici. Notez que, comme une instance ClickHouse Cloud se compose de plusieurs nœuds de calcul, nous utilisons la fonction de table s3Cluster à la place de la fonction de table
gcs. Cette fonction fonctionne également avec les buckets GCS et utilise tous les nœuds d’un service ClickHouse Cloud pour charger les données en parallèle.
- La fonctionnalité d’exportation de BigQuery prend en charge un filtre permettant d’exporter un sous-ensemble de données.
- BigQuery prend en charge l’exportation aux formats Parquet, Avro, JSON et CSV, ainsi qu’avec plusieurs types de compression, tous pris en charge par ClickHouse.
- GCS prend en charge la gestion du cycle de vie des objets, ce qui permet de supprimer, après une période spécifiée, les données qui ont été exportées puis importées dans ClickHouse.
- Google autorise gratuitement l’exportation de jusqu’à 50 To par jour vers GCS. Les utilisateurs ne paient que le stockage GCS.
- Les exportations produisent automatiquement plusieurs fichiers, chacun étant limité à un maximum de 1 Go de données de table. Cela est avantageux pour ClickHouse, car les importations peuvent ainsi être parallélisées.
Réplication en temps réel ou CDC via des requêtes planifiées
Conception des schémas
posts. Le schéma BigQuery correspondant est présenté ci-dessous :
Optimisation des types
INSERT INTO SELECT, en lisant les données exportées à partir de gcs à l’aide de la fonction de table gcs. Notez que sur ClickHouse Cloud, vous pouvez également utiliser la fonction de table s3Cluster compatible avec gcs pour répartir le chargement sur plusieurs nœuds :
En quoi les clés primaires de ClickHouse sont-elles différentes ?
- L’efficacité de la mémoire et du disque est primordiale à l’échelle à laquelle ClickHouse est souvent utilisé. Les données sont écrites dans les tables ClickHouse en fragments appelés parts, selon des règles appliquées pour fusionner ces parts en arrière-plan. Dans ClickHouse, chaque part possède son propre index primaire. Lorsque des parts sont fusionnées, les index primaires de la part fusionnée le sont également. À noter que ces index ne sont pas construits pour chaque ligne. À la place, l’index primaire d’une part contient une entrée d’index par groupe de lignes : cette technique s’appelle l’indexation sparse.
- L’indexation sparse est possible parce que ClickHouse stocke les lignes d’une part sur disque selon l’ordre d’une clé spécifiée. Au lieu de localiser directement des lignes individuelles (comme un index basé sur un B-Tree), l’index primaire sparse permet d’identifier rapidement (via une recherche binaire sur les entrées d’index) des groupes de lignes susceptibles de correspondre à la requête. Les groupes de lignes potentiellement correspondantes ainsi localisés sont ensuite lus en parallèle et transmis au moteur ClickHouse afin de trouver les correspondances. Cette conception permet à l’index primaire de rester compact (il tient entièrement en mémoire principale) tout en accélérant significativement le temps d’exécution des requêtes, en particulier pour les requêtes par plage typiques des cas d’usage analytiques. Pour plus de détails, nous recommandons ce guide détaillé.
Toutes les colonnes d’une table seront triées en fonction de la valeur de la clé de tri spécifiée, qu’elles soient ou non incluses dans la clé elle-même. Par exemple, siCreationDateest utilisée comme clé, l’ordre des valeurs dans toutes les autres colonnes correspondra à l’ordre des valeurs de la colonneCreationDate. Plusieurs clés de tri peuvent être spécifiées ; l’ordonnancement suivra alors la même sémantique qu’une clauseORDER BYdans une requêteSELECT.
Choix d’une clé de tri
Techniques de modélisation des données
Partitions
PARTITION BY. Cette clause peut contenir une expression SQL sur une ou plusieurs colonnes, dont le résultat détermine vers quelle partition une ligne est envoyée.
Les data parts sont associées logiquement à chaque partition sur le disque et peuvent être interrogées de manière isolée. Dans l’exemple ci-dessous, nous partitionnons la table Posts par année à l’aide de l’expression toYear(CreationDate). À mesure que des lignes sont insérées dans ClickHouse, cette expression est évaluée pour chaque ligne ; les lignes sont ensuite dirigées vers la partition correspondante sous la forme de nouvelles data parts appartenant à cette partition.
Applications
- Gestion des données - Dans ClickHouse, vous devez considérer le partitionnement avant tout comme une fonctionnalité de gestion des données, et non comme une technique d’optimisation des requêtes. En séparant logiquement les données à l’aide d’une clé, chaque partition peut être manipulée indépendamment, par exemple supprimée. Cela vous permet de déplacer efficacement des partitions, et donc des sous-ensembles, entre les niveaux de stockage en fonction du temps, ou de faire expirer des données / les supprimer efficacement du cluster via cette instruction. Dans l’exemple ci-dessous, nous supprimons des publications de 2008 :
- Optimisation des requêtes - Bien que les partitions puissent améliorer les performances des requêtes, cela dépend fortement des schémas d’accès. Si les requêtes ne ciblent qu’un petit nombre de partitions (idéalement une seule), les performances peuvent s’en trouver améliorées. Cela n’est généralement utile que si la clé de partitionnement ne fait pas partie de la clé primaire et que vous filtrez sur celle-ci. En revanche, les requêtes qui doivent couvrir un grand nombre de partitions peuvent être moins performantes qu’en l’absence de partitionnement (car le partitionnement peut entraîner la création d’un plus grand nombre de parts). L’avantage de cibler une seule partition sera encore moins marqué, voire nul, si la clé de partitionnement apparaît déjà tôt dans la clé primaire. Le partitionnement peut également être utilisé pour optimiser les requêtes
GROUP BYsi les valeurs de chaque partition sont uniques. Cependant, de manière générale, vous devez d’abord vous assurer que la clé primaire est bien optimisée, et n’envisager le partitionnement comme technique d’optimisation des requêtes que dans des cas exceptionnels, lorsque les schémas d’accès portent sur un sous-ensemble spécifique et prévisible des données, par exemple un partitionnement par jour, avec la plupart des requêtes concentrées sur le dernier jour.
Recommandations
ORDER BY.
En interne, ClickHouse crée des parts pour les données insérées. À mesure que davantage de données sont insérées, le nombre de parts augmente. Afin d’éviter un nombre excessivement élevé de parts, ce qui dégrade les performances des requêtes (car il y a davantage de fichiers à lire), les parts sont fusionnées dans un processus asynchrone exécuté en arrière-plan. Si le nombre de parts dépasse une limite préconfigurée, ClickHouse lèvera alors une exception lors de l’insertion, sous la forme d’une erreur « too many parts ». Cela ne devrait pas se produire en fonctionnement normal et n’arrive que si ClickHouse est mal configuré ou mal utilisé, par exemple avec de nombreuses petites insertions. Comme les parts sont créées séparément pour chaque partition, l’augmentation du nombre de partitions entraîne aussi une augmentation du nombre de parts, c.-à-d. qu’il correspond à un multiple du nombre de partitions. Les clés de partitionnement à cardinalité élevée peuvent donc provoquer cette erreur et doivent être évitées.
Vues matérialisées vs projections
ORDER BY pour une table.
Dans la modélisation des données ClickHouse, nous expliquons comment les vues matérialisées peuvent être utilisées
dans ClickHouse pour précalculer des agrégations, transformer des lignes et optimiser les requêtes
pour différents modes d’accès. Pour ce dernier point, nous avons donné un exemple dans lequel
la vue matérialisée envoie des lignes vers une table cible avec une clé de tri différente
de celle de la table d’origine dans laquelle les insertions sont effectuées.
Par exemple, considérez la requête suivante :
UserId
n’est pas la clé de tri. Auparavant, nous avions résolu ce problème à l’aide d’une vue matérialisée
servant de table de correspondance pour le PostId. Le même problème peut être résolu avec une projection.
La commande ci-dessous ajoute une projection avec ORDER BY user_id.
ALTER, sa création est asynchrone
lorsque la commande MATERIALIZE PROJECTION est exécutée. Vous pouvez suivre la progression
de cette opération à l’aide de la requête suivante, en attendant que is_done=1.
EXPLAIN, nous pouvons également confirmer que la projection a bien été utilisée pour exécuter cette requête :
Quand utiliser les projections
- Une réorganisation complète des données est nécessaire. Bien que l’expression de la projection puisse, en théorie, utiliser un
GROUP BY,les vues matérialisées sont plus efficaces pour maintenir des agrégats. L’optimiseur de requêtes est également plus susceptible d’exploiter des projections qui reposent sur une simple réorganisation, c.-à-d.SELECT * ORDER BY x. Vous pouvez sélectionner un sous-ensemble de colonnes dans cette expression afin de réduire l’empreinte de stockage. - Les utilisateurs sont à l’aise avec l’augmentation associée de l’empreinte de stockage et le surcoût lié à la double écriture des données. Testez l’impact sur la vitesse d’insertion et évaluez le surcoût de stockage.
Réécriture de requêtes BigQuery dans ClickHouse
ClickHouse
Fonctions d’agrégation
argMax pour calculer la question la plus vue de chaque année.
BigQuery
ClickHouse
Expressions conditionnelles et tableaux
HAVING et SELECT.
BigQuery
ClickHouse