ServicesÀ proposNotesContact Me contacter →
EN FR
Note

Backfill Microbatch et protection contre le full refresh

Comment utiliser les commandes de backfill microbatch intégrées à dbt, relancer les batchs en échec, et protéger les grandes tables incrémentielles contre les full refreshes accidentels.

Planté
dbtincremental processingdata engineering

Avec les modèles incrémentiels traditionnels, retraiter une plage de dates spécifique nécessite des scripts personnalisés, des overrides de variables dbt, ou des full refreshes ciblés avec une gestion manuelle des partitions. Microbatch fournit des flags CLI intégrés pour le backfill ciblé, la relance par batch en cas d’échec et la protection contre le full refresh.

Backfill ciblé avec des flags CLI

Les flags --event-time-start et --event-time-end permettent de spécifier des plages de dates exactes à retraiter :

Terminal window
# Retraiter du 1er au 3 septembre 2024
dbt run --select int__sessions_aggregated \
--event-time-start "2024-09-01" \
--event-time-end "2024-09-04"

dbt génère des requêtes séparées pour chaque batch dans cette plage. Avec batch_size='day', cela exécute trois requêtes de batch (1er, 2 et 3 septembre). Chaque batch remplace la période correspondante dans la table cible en utilisant la stratégie d’entrepôt sous-jacenteinsert_overwrite sur BigQuery, delete+insert sur Snowflake, replace_where sur Databricks.

La date de fin est exclusive, conformément aux conventions standard des intervalles. --event-time-end "2024-09-04" traite jusqu’au 4 septembre non inclus.

Ces flags fonctionnent avec la sélection de modèles, donc on peut faire un backfill d’un seul modèle ou d’un groupe :

Terminal window
# Backfill de tous les modèles avec le tag microbatch+
dbt run --select tag:microbatch --event-time-start "2024-09-01" --event-time-end "2024-10-01"
# Backfill d'un modèle et toutes ses dépendances en aval
dbt run --select int__sessions_aggregated+ --event-time-start "2024-09-01" --event-time-end "2024-09-04"

Cela remplace les patterns de backfill personnalisés que les équipes construisent typiquement avec des modèles incrémentiels traditionnels — overrides de variables, scripts shell qui bouclent sur des dates, ou SQL ad hoc qui supprime et réinsère manuellement des partitions.

Relance par batch

Quand une exécution microbatch échoue en cours de traitement, dbt retry reprend depuis le batch en échec plutôt que de recommencer depuis le début :

Terminal window
# L'exécution initiale traite 30 jours, échoue au jour 17
dbt run --select int__sessions_aggregated \
--event-time-start "2024-09-01" \
--event-time-end "2024-10-01"
# Relancer uniquement le batch en échec (jour 17) et continuer depuis là
dbt retry

Avec un incrémental traditionnel, un échec dans un backfill de 30 jours signifie relancer les 30 jours. Les 16 premiers jours de travail sont perdus. Avec microbatch, les jours 1-16 sont déjà committés dans la table cible, et la relance démarre au jour 17.

C’est particulièrement précieux pour :

  • Les grands backfills historiques où recommencer depuis zéro coûte réellement de l’argent (octets scannés BigQuery, crédits de calcul Snowflake)
  • Les systèmes sources instables où les échecs intermittents sont courants et relancer un seul batch est bien moins coûteux que de tout relancer
  • Les requêtes sujettes aux timeouts où des batchs individuels peuvent échouer à cause de limites de ressources mais la plupart des batchs se terminent correctement

Le mécanisme de relance fonctionne parce que chaque batch est une opération autonome. dbt suit quels batchs ont réussi et lesquels ont échoué dans les artefacts d’exécution. La commande dbt retry lit ces artefacts et ré-exécute uniquement les échecs.

Full refresh borné

Le --full-refresh traditionnel reconstruit une table de zéro — depuis la date begin jusqu’à maintenant, en traitant tout. Pour une table avec des années d’historique, c’est coûteux et lent. Microbatch permet de borner un full refresh à une plage temporelle spécifique :

Terminal window
# Full refresh uniquement janvier 2024
dbt run --full-refresh \
--select int__sessions_aggregated \
--event-time-start "2024-01-01" \
--event-time-end "2024-02-01"

Cela reconstruit uniquement la plage spécifiée tout en laissant le reste de la table intact. C’est la différence entre « tout reconstruire depuis 2020 » et « reconstruire uniquement le mois qui avait des données incorrectes ».

C’est particulièrement utile quand :

  • Un système source a corrigé des données historiques pour une période spécifique
  • La logique de transformation a été modifiée et nécessite de retraiter une fenêtre bornée
  • Un changement de schéma nécessite un retraitement mais n’affecte que les données après une certaine date

Protéger contre les full refreshes accidentels

Les grandes tables incrémentielles peuvent être extrêmement coûteuses à reconstruire. Un dbt run --full-refresh imprudent sur une table avec 3 ans de données d’événements peut prendre des heures et coûter des centaines d’euros en calcul. Microbatch fournit un filet de sécurité :

{{ config(
materialized='incremental',
incremental_strategy='microbatch',
event_time='event_occurred_at',
batch_size='day',
begin='2020-01-01',
full_refresh=false
) }}

Avec full_refresh=false, exécuter dbt run --full-refresh sur ce modèle échoue avec une erreur plutôt que de reconstruire silencieusement toute la table. C’est un garde-fou, pas un verrou permanent — les refreshes bornés utilisant --event-time-start et --event-time-end restent possibles.

Cette protection importe surtout pour :

  • Les tables de production où un full refresh accidentel causerait des heures d’indisponibilité pendant la reconstruction de la table
  • Les tables d’événements à grand volume où le coût de reconstruction est significatif (pensez à des téraoctets de scans BigQuery à 6,25$/TB)
  • Les tables sans fenêtre de reconstruction naturelle — certaines tables sont trop grandes pour être reconstruites même sur une nuit

Le paramètre full_refresh=false s’applique au niveau du modèle. Il peut être défini globalement dans dbt_project.yml pour tous les modèles microbatch et overridé par modèle où les full refreshes sont acceptables :

dbt_project.yml
models:
my_project:
marts:
+full_refresh: false # Protéger tous les modèles mart
staging:
+full_refresh: true # Le staging peut être reconstruit librement

Patterns opérationnels

Backfill planifié après des pannes source

Quand un système source a une panne connue, un backfill ciblé pour la fenêtre affectée peut être planifié une fois que la source est rétablie :

Terminal window
# La source était en panne du 15 au 17 mars, données backfillées le 20 mars
dbt run --select tag:source_dependent \
--event-time-start "2024-03-15" \
--event-time-end "2024-03-18"

Reconstruction historique par morceaux

Pour les très grandes tables où traiter tout l’historique d’un coup dépasserait les limites de ressources ou serait inacceptablement lent, traiter par morceaux mensuels :

Terminal window
# Reconstruire 2024 un mois à la fois
for month in 01 02 03 04 05 06 07 08 09 10 11 12; do
dbt run --select int__sessions_aggregated \
--event-time-start "2024-${month}-01" \
--event-time-end "2024-$((10#$month + 1))-01" || break
done

Chaque morceau est traité indépendamment. Si le mois 7 échoue, les mois 1-6 sont déjà committés, et seul le mois 7 doit être relancé.

Validation des résultats de backfill

Après un backfill, comparer les batchs retraités aux comptages ou agrégats attendus :

-- Vérifier que les jours backfillés ont les comptages de lignes attendus
SELECT
DATE(session__started_at) AS batch_date,
COUNT(*) AS row_count
FROM int__sessions_aggregated
WHERE session__started_at >= '2024-09-01'
AND session__started_at < '2024-09-04'
GROUP BY 1
ORDER BY 1;

C’est basique, mais cela détecte les échecs de backfill les plus courants : batchs vides (données source indisponibles), batchs dupliqués (chevauchement de lookback mal géré), et écarts de comptage par rapport à la source.

Comparaison avec les approches de backfill traditionnelles

AspectIncrémental traditionnelMicrobatch
Mécanisme de backfillOverrides de variables, scripts personnalisésFlags --event-time-start/end intégrés
Récupération sur échecRetraitement de toute la plageRelance des seuls batchs en échec
Portée du full refreshTable entièreBorné à une plage de dates spécifique
ProtectionAucune intégréeConfig full_refresh=false
GranularitéCe que le script gèrePar batch (heure/jour/mois)

Avec microbatch, la capacité de backfill fait partie de la configuration du modèle plutôt que d’un ensemble de scripts séparé. La CLI dbt standard gère le backfill ciblé sans procédures personnalisées.