Snowflake MigrationClickHouse Workshops

01 Environnement source

Provisionnez un environnement Snowflake représentatif d’un déploiement client réel — 50 millions de lignes, un pipeline dbt Medallion, un producteur de courses actif et trois tableaux de bord Superset.

Point de départ

Module 00 terminé : la chaîne d’outils est installée, les deux comptes d’essai cloud sont actifs, le dépôt est cloné et l’environnement virtuel dbt-snowflake est prêt. Ce module prend environ 45 minutes et consomme à peu près 2 à 4 crédits Snowflake.

Pourquoi

On ne peut pas préparer une migration à partir d’une source jouet. Une table plate de quelques lignes permettrait d’éviter toutes les décisions qui rendent une migration réelle difficile. Ce module reproduit plutôt un véritable déploiement client : une colonne VARIANT contenant du JSON semi-structuré, un stream CDC, des tâches planifiées, un pipeline MERGE incrémentiel et une couche BI qui s’appuie sur l’ensemble. Chacun de ces éléments donnera lieu à une décision précise dans le module 02. Ce module vous donne donc un cas concret auquel vous référer lorsque ces choix se présenteront, plutôt qu’une simple abstraction.

Concepts — fonctionnement interne

Infrastructure (Terraform). L’exécution de setup.sh provisionne :

  • Warehouses — TRANSFORM_WH (SMALL, pour l’ELT) et ANALYTICS_WH (MEDIUM, pour la BI), avec un moniteur de ressources (ANALYTICS_WH_MONITOR) plafonné à 50 crédits par mois.
  • Base de données — NYC_TAXI_DB, avec trois schémas : RAW, STAGING, ANALYTICS.
  • Rôles — TRANSFORMER_ROLE, ANALYST_ROLE, DBT_ROLE, LOADER_ROLE.

Environnement source Snowflake : un générateur synthétique ponctuel et un producteur Docker continu insèrent des données dans NYC_TAXI_DB, lues par trois tableaux de bord Superset via le warehouse analytics

La structure Medallion. Les données traversent trois couches dans NYC_TAXI_DB :

  • RAW — TRIPS_RAW (50 millions de courses synthétiques, avec une colonne VARIANT TRIP_METADATA qui simule la télémétrie d’une application — c’est le défi de migration JSON) et les tables de dimensions (DIM_TAXI_ZONES, DIM_PAYMENT_TYPE, DIM_VENDOR).
  • STAGING — vues dbt qui nettoient les types et désimbriquent la colonne VARIANT.
  • ANALYTICS — tables et modèles incrémentiels dbt : fact_trips (50 millions de lignes, stratégie MERGE), quatre tables de dimensions et agg_hourly_zone_trips (agrégat incrémentiel).

Deux objets Snowflake font avancer ce pipeline de manière autonome, indépendamment de dbt :

  • TRIPS_CDC_STREAM — un stream Change Data Capture sur TRIPS_RAW.
  • CDC_CONSUME_TASK — lit ce stream toutes les 5 minutes (s’exécute dans RAW et reprend pendant la préparation) — ainsi que HOURLY_AGG_TASK, qui actualise l’agrégat horaire chaque heure (s’exécute dans STAGING et reprend après la création par dbt).

Dans NYC_TAXI_DB : TRIPS_RAW et sa colonne de métadonnées VARIANT alimentent un stream CDC et une tâche de consommation planifiée, tandis que dbt crée les vues de préparation, puis les tables de faits, de dimensions et d’agrégats horaires

Superset. Les trois tableaux de bord lisent le schéma ANALYTICS par l’intermédiaire de ANALYTICS_WH ; aucun n’accède directement à RAW ou STAGING. C’est ce chemin de lecture que vous reproduirez plus tard du côté ClickHouse.

Étape 1 — Configurer les identifiants

cd "$(git rev-parse --show-toplevel)/workshop_public/snowflake_migration_lab/01-setup-snowflake"

cp .env.example .env
# Edit .env with your Snowflake credentials

cp dbt/nyc_taxi_dbt/profiles.yml.example ~/.dbt/profiles.yml
# Edit ~/.dbt/profiles.yml with your account details

.env et ~/.dbt/profiles.yml sont tous deux ignorés par Git : ils contiennent votre compte Snowflake, votre utilisateur et votre mot de passe. Ne validez jamais ces deux fichiers dans le dépôt.

Étape 2 — Exécuter la préparation

cd "$(git rev-parse --show-toplevel)/workshop_public/snowflake_migration_lab/01-setup-snowflake"
source .env && ./setup.sh

Comptez 5 à 10 minutes, principalement consacrées à la génération de 50 millions de courses synthétiques avec TABLE(GENERATOR). En une seule exécution, setup.sh provisionne l’infrastructure Terraform, charge TRIPS_RAW, lance la construction dbt et démarre Docker Compose (producteur de courses et Superset).

Étape 3 — Démarrer le producteur et Superset

setup.sh démarre Docker Compose avec le bon environnement, enregistre la connexion Snowflake dans Superset et importe automatiquement les trois tableaux de bord.

Dans les ZIP de tableaux de bord enregistrés sous superset/dashboards/, la valeur sqlalchemy_uri a été remplacée par des valeurs fictives (LAB_USER, MYORG-MYACCOUNT). L’import automatique réécrit l’URI depuis votre .env ; l’opération est donc transparente lors de l’exécution de setup.sh. En revanche, si vous importez manuellement un ZIP dans l’interface Superset, la connexion créée utilisera ces valeurs fictives et échouera. Modifiez-la ensuite afin d’utiliser votre véritable compte Snowflake.

Si vous devez redémarrer Superset manuellement :

cd "$(git rev-parse --show-toplevel)/workshop_public/snowflake_migration_lab/01-setup-snowflake/superset"
docker-compose --env-file ../.env up -d

L’option --env-file ../.env charge les variables d’environnement depuis le répertoire parent.

Sources de données des tableaux de bord Superset : trois tableaux de bord opérationnels lisent le schéma analytics par l’intermédiaire du warehouse analytics

Les trois tableaux de bord sont Operations Command Center, Executive Weekly Report et Driver & Quality Analytics (volontairement lent, car il servira de cible au benchmark ClickHouse plus tard). Pour construire intégralement les tableaux de bord — sources de données, graphiques et filtres — consultez Superset sur Snowflake.

Étape 4 — Maintenir dbt à jour

Le producteur de courses insère en continu environ 60 courses par minute dans TRIPS_RAW. Pour garder fact_trips et agg_hourly_zone_trips à jour pendant votre travail, exécutez la boucle d’actualisation dbt dans un autre terminal :

cd "$(git rev-parse --show-toplevel)/workshop_public/snowflake_migration_lab/01-setup-snowflake"

# Default: refresh every 5 minutes (auto-sources .env)
./scripts/run_dbt.sh

# Custom interval
./scripts/run_dbt.sh --interval 15m

# Run once and exit
./scripts/run_dbt.sh --once

# Include dbt tests after each run
./scripts/run_dbt.sh --test
OptionEffet
--interval <n>Délai entre les exécutions : 30s, 5m, 1h ou nombre de secondes sans unité (valeur par défaut : 5m)
--onceExécute une seule actualisation, puis quitte
--testExécute dbt test après chaque dbt run

Le script fonctionne toujours de manière incrémentielle : il n’effectue jamais de --full-refresh, si bien que les lignes insérées par le producteur sont conservées. Appuyez sur Ctrl-C à tout moment pour l’arrêter ; laissez-le fonctionner dans son propre terminal pendant le reste de l’atelier, car le module 03 en dépend encore.

Étape 5 — Explorer la bibliothèque de requêtes

cd "$(git rev-parse --show-toplevel)/workshop_public/snowflake_migration_lab/01-setup-snowflake"

Le répertoire de requêtes (workshop_public/snowflake_migration_lab/01-setup-snowflake/queries/) contient sept fichiers SQL annotés. Chacun s’exécute dans l’environnement Snowflake que vous venez de créer et comporte un défi de migration volontaire que le module 02 traduira pour ClickHouse :

RequêteConstructionDéfi de migration
Q1DATE_TRUNC, DATEADDLégère différence de syntaxe
Q2Fenêtre ROWS BETWEENPresque identique dans ClickHouse
Q3QUALIFYNatif dans ClickHouse depuis la version 24.5, mais tout de même réécrit ici sous forme de sous-requête pour rester portable
Q4LATERAL FLATTENAucun équivalent — utiliser JSONExtract ou désimbriquer au préalable
Q5Chemin avec deux-points de VARIANTRemplacer par JSONExtractFloat/JSONExtractString
Q6MERGE INTOAucun équivalent — utiliser ReplacingMergeTree
Q7Streams SnowflakeRetirés lors de la bascule — les écritures actives vont directement dans ClickHouse via le producteur

Ouvrez chaque fichier et exécutez-le dans votre environnement Snowflake avant de continuer. Le bloc de commentaires de chaque requête esquisse déjà l’équivalent ClickHouse ; vous écrirez et exécuterez réellement cette version dans le module 02.

Comment vérifier que vous avez terminé

cd "$(git rev-parse --show-toplevel)/workshop_public/snowflake_migration_lab/01-setup-snowflake"
source .env && ./scripts/verify_environment.sh

Ce script vérifie :

  1. Base et schémas — NYC_TAXI_DB existe avec RAW, STAGING, ANALYTICS.
  2. Tables et données — TRIPS_RAW contient environ 50 millions de lignes, FACT_TRIPS est remplie et les dimensions existent.
  3. Stream CDC — TRIPS_CDC_STREAM existe sur TRIPS_RAW.
  4. Tâches planifiées — CDC_CONSUME_TASK et HOURLY_AGG_TASK sont dans l’état started.
  5. Activité CDC — les tâches ont été exécutées récemment.
  6. Flux du producteur — le producteur de courses insère des données en continu.
  7. Superset — les tableaux de bord BI sont accessibles sur http://localhost:8088.

Pour effectuer la vérification à la main, SHOW TASKS LIKE '%TASK' IN DATABASE NYC_TAXI_DB; avec le rôle ACCOUNTADMIN (qui possède les tâches) confirme que les deux tâches fonctionnent.

Pour la suite

Vous reviendrez plusieurs fois dans cet environnement au cours des prochains modules, et une exécution complète de ./setup.sh coûte 5 à 10 minutes qu’il est inutile de répéter après chaque modification d’un fichier Terraform ou d’un modèle dbt. setup.sh propose précisément les options suivantes :

OptionQuand l’utiliser
(aucune)Première exécution. Provisionne tout et génère 50 millions de lignes synthétiques (environ 12 min au total).
--skip-seedL’infrastructure existe déjà et TRIPS_RAW contient des données. Ignore la génération synthétique (environ 8 min gagnées).
--skip-dbtLes objets Snowflake existent, mais les transformations dbt n’ont pas besoin d’être relancées (par exemple pour tester Terraform).
--skip-supersetDocker ne fonctionne pas ou la couche BI n’est pas encore nécessaire.
--full-refreshForce dbt à reconstruire tous les modèles incrémentiels (par exemple après une modification de schéma).

Les options peuvent être combinées. Deux combinaisons courantes :

# Re-run after a Terraform or SQL change — skip the ~10 min data load
./setup.sh --skip-seed

# Iterate on dbt models only — skip everything else
./setup.sh --skip-seed --skip-superset

Remarque sur le coût. Le chargement initial dure environ 12 minutes pour 2 crédits (environ 6 $), et une construction dbt complète environ 8 minutes pour 1,5 crédit (environ 5 $). Une session de 8 heures par partenaire ajoute à peu près 12 crédits (environ 36 $). Les warehouses se suspendent automatiquement lorsqu’ils sont inactifs ; le coût cesse donc de s’accumuler entre les sessions. Le total quotidien par partenaire est d’environ 16 crédits, soit 47 $.

État final

Snowflake est opérationnel : NYC_TAXI_DB est entièrement construit, le stream CDC et les deux tâches planifiées fonctionnent, le producteur écrit environ 60 courses par minute dans TRIPS_RAW, et les trois tableaux de bord Superset sont disponibles sur http://localhost:8088.

Laissez le producteur fonctionner. N’arrêtez pas la pile Docker Compose et n’exécutez pas ./teardown.sh : les modules 02 à 05 dépendent de cet environnement actif, et la bascule du module 05 mesure précisément l’écart créé par le producteur entre Snowflake et ClickHouse pendant la migration. Supprimer l’environnement maintenant ferait échouer le reste de l’atelier d’une manière difficile à rattacher à cette étape. La suppression est traitée à la fin du module 05, pas ici.

Sur cette page

Suivre votre progression ?

Facultatif. Nous envoyons un lien par e-mail pour confirmer votre adresse ; la progression est enregistrée après son ouverture.

Utilisez votre adresse e-mail professionnelle, et non une adresse personnelle.

Le suivi de la progression exige aussi d’accepter les Conditions d’utilisation actuelles dans les Paramètres de confidentialité.

FR