Explorez en profondeur les formats open table

Vous maîtrisez maintenant les opérations fondamentales avec Delta Lake. Marc est impressionné par vos premiers résultats chez GreenFarm, mais il vous lance un nouveau défi : les performances. Vos tables de capteurs IoT grossissent chaque jour, les requêtes ralentissent, et les coûts de stockage augmentent. Il est temps d'explorer les fonctionnalités avancées de Delta Lake pour optimiser vos performances, gérer intelligemment votre historique de données, et suivre les modifications en temps réel. Ces techniques transformeront vos tables en véritables moteurs de performance. C'est parti !

Optimisez les performances des tables Delta

Delta Lake n’est pas seulement un format transactionnel fiable. C’est aussi un système de stockage conçu pour être optimisé dans le temps. Chez GreenFarm, chaque parcelle agricole génère des milliers de mesures par jour :  température, humidité, taux d’azote, salinité…

Très rapidement, cela se traduit par :

  • une explosion du nombre de fichiers Parquet ;

  • des requêtes plus lentes ;

  • une pression accrue sur le cluster Spark ;

  • des coûts de lecture et de calcul en hausse.

Delta Lake propose plusieurs mécanismes complémentaires pour répondre à ces enjeux.

Le Data Skipping

Delta Lake s’appuie sur les métadonnées stockées dans les fichiers Parquet : minimum, maximum, nombre de valeurs nulles, etc. Lorsqu’une requête filtre sur une colonne, par exemple :

humidity > 45

Delta Lake peut éviter d’ouvrir les fichiers dont les statistiques indiquent qu’ils ne contiennent aucune valeur pertinente. C’est ce mécanisme que l’on appelle le Data Skipping.

Partitionnez intelligemment les données

Le partitionnement consiste à organiser physiquement les données selon une ou plusieurs colonnes clés.

Chez GreenFarm, deux choix se sont révélés particulièrement efficaces :

  • la date, car les analyses sont souvent journalières ;

  • la parcelle agricole, pour isoler les zones géographiques.

Exemple en pySpark :

(df.write
  .format("delta")
  .mode("overwrite")
  .partitionBy("date")
  .saveAsTable("sensors_partitioned")   # version table
)
## ou
(df.write
  .format("delta")
  .mode("overwrite")
  .partitionBy("date")
  .save("data/sensors_partitioned")
)

Structure obtenue :

/date=2025-11-09/part-*.parquet

/date=2025-11-10/part-*.parquet

Compactez les fichiers avec OPTIMIZE (PySpark)

Avec le temps, une table Delta accumule naturellement de nombreux petits fichiers Parquet, issus des écritures incrémentales, des mises à jour et des fusions. Même si Delta Lake garantit la cohérence des données, cette fragmentation a un impact direct sur :

  • les temps de lecture ;

  • le nombre de fichiers scannés par Spark ;

  • les coûts de calcul.

La commande OPTIMIZE permet de regrouper ces petits fichiers en fichiers plus volumineux et plus efficaces à lire.

OPTIMIZE : le cas le plus simple

Exemple en Spark SQL:

spark.sql("OPTIMIZE sensors_delta")

Exemple en Python :

from delta.tables import DeltaTable
delta_table = DeltaTable.forPath(spark, "data/sensors_delta")
delta_table.optimize().executeCompaction()

Cette commande :

  • compacte les petits fichiers Parquet ;

  • sur l’ensemble de la table ;

  • sans Z-ORDER.

OPTIMIZE ciblé

Pour optimiser uniquement une partie des données, on utilise un prédicat : 

spark.sql("""
    OPTIMIZE sensors_delta
    WHERE date >= '2025-01-01'
""")

 

Ou de manière dynamique :

spark.sql("""
OPTIMIZE sensors_delta
WHERE date >= current_timestamp() - INTERVAL 1 DAY
""")

 

C’est la bonne pratique chez GreenFarm :

  • on optimise surtout les données récentes ;

  • on limite les coûts ;

  • on garde de bonnes performances analytiques.

Accélérez les filtres avec Z-ORDER

Lorsque certaines colonnes sont très fréquemment utilisées dans les filtres (sensor_id, parcel, date), Delta Lake propose Z-ORDER.Z-ORDER  réorganise physiquement les données afin de rapprocher les valeurs similaires sur plusieurs colonnes, ce qui améliore fortement le Data Skipping.

Exemple en Spark SQL:

spark.sql("""
    OPTIMIZE sensors_delta
    ZORDER BY (sensor_id)
""")

Exemple en Python :

DeltaTable.forPath(spark, "data/sensors_delta") \
    .optimize() \
    .executeZOrderBy("sensor_id")

Gérez le Liquid Clustering

Dans la section précédente, vous avez découvertZ-ORDER, une technique puissante mais qui nécessite des optimisations manuelles régulières. Pour répondre aux limites de cette approche, Delta Lake introduit le Liquid Clustering, conçu comme l’évolution naturelle deZ-ORDER.

Du Z-ORDER au Liquid Clustering

Z-ORDER impose de :

  • choisir des colonnes fixes ;

  • relancer régulièrement des opérationsOPTIMIZE ZORDER;

  • maintenir manuellement l’organisation physique des données.

Le Liquid Clustering remplaceZ-ORDERen automatisant cette organisation.

Avec le Liquid Clustering :

  • vous ne créez pas de partitions rigides ;

  • l’organisation des données est dynamique ;

  • Delta Lake rééquilibre automatiquement les fichiers dans le temps.

Activez le Liquid Clustering (PySpark)

spark.sql("""
ALTER TABLE sensors_delta
SET TBLPROPERTIES (
  delta.liquidClustering.enabled = true,
  delta.liquidClustering.columns = 'sensor_id'
)
""")

 

Pour déclencher explicitement un reclustering :

spark.sql("REORG TABLE sensors_delta APPLY (CLUSTERING)")

Quelques bonnes pratiques (et points d’attention) : 

  • choisissez des colonnes fréquemment filtrées ;

  • privilégiez une bonne distribution des valeurs ;

  • évitez de modifier souvent les colonnes de clustering ;

  • anticipez le coût du reclustering sur les très grandes tables

Utilisez le Time Travel pour la gestion des données

Chaque opération Delta crée une nouvelle version immuable, enregistrée dans le journal des transactions. Le Time Travel de Delta Lake est une fonctionnalité clé qui vous permet d'accéder et de revenir à des versions précédentes de vos données. Cette capacité est rendue possible par le journal des transactions qui versionne automatiquement les données de la table. Lorsqu'une opération comme UPDATE, DELETE ou MERGE est effectuée, les fichiers de données concernés ne sont pas physiquement supprimés immédiatement ; ils sont seulement marqués logiquement comme obsolètes dans le journal des transactions.

Lisez et restaurez des versions antérieures

Pour interroger des versions antérieures, vous pouvez spécifier un numéro de version ou un horodatage dans votre requête. La commande DESCRIBE HISTORY vous fournit tous les détails nécessaires : la version, l'horodatage, l'opération effectuée, ses paramètres et des métriques comme le nombre de fichiers ajoutés ou supprimés et le nombre de lignes affectées. Pour GreenFarm, cela signifie pouvoir revenir aux données de certification bio d'il y a trois semaines pour comprendre un écart dans les rapports de conformité. Lire une version précise :

Exemple en Spark SQL:

display(spark.sql("SELECT * FROM sensors_delta VERSION AS OF 3 LIMIT 10"))

Exemple en pySpark :

df_v3 = spark.read.format("delta").option("versionAsOf", 3).table("sensors_delta")
display(df_v3.limit(10))

 

Restaurer une version complète :

spark.sql("RESTORE TABLE sensors_delta TO VERSION AS OF 3")

 

Rétention, VACUUM et compromis opérationnels

Parlons maintenant de la rétention des données. Les fichiers de données sous-jacents ne sont jamais supprimés automatiquement, mais les fichiers journaux sont nettoyés automatiquement après la création de points de contrôle. Par défaut, les tables Delta conservent l'historique des commits pendant 30 jours, ce qui permet le Time Travel sur cette période. 

Vous pouvez modifier cette durée de rétention pour les fichiers de données (delta.deletedFileRetentionDuration) et les fichiers journaux (delta.logRetentionDuration) via  ALTER TABLE.

La commande VACUUMest votre outil de nettoyage. Elle supprime physiquement les anciennes versions de fichiers de données qui ne sont plus nécessaires et qui sont plus anciennes que le seuil de rétention défini.VACUUM  ignore les répertoires commençant par un underscore (comme _delta_log) et constitue une opération sans annulation : une fois les données supprimées, elles sont définitivement perdues. Utilisez cette commande avec précaution pour équilibrer les besoins de Time Travel et les coûts de stockage. Delta Lake conserve les anciennes versions pendant une durée configurable (7 jours par défaut).

On configure au niveau table:

spark.sql("""
ALTER TABLE sensors_delta
SET TBLPROPERTIES (
  delta.deletedFileRetentionDuration = 'interval 24 hours',
  delta.logRetentionDuration = 'interval 24 hours'
)
""")

 

Puis:

spark.sql("VACUUM sensors_delta RETAIN 24 HOURS")

Exploitez le Change Data Feed (CDF)

Certaines applications n’ont besoin que des changements, pas de l’intégralité des données.

C’est exactement le rôle du Change Data Feed (CDF).

Du CDC classique au CDF Delta Lake

Avant de plonger dans le Change Data Feed, comprenons le concept de Change Data Capture (CDC). Il s'agit d'une méthode permettant d'extraire chaque événement de modification (insertion, mise à jour, suppression) qui se produit dans une base de données. Le CDC est fréquemment utilisé pour répliquer des données entre bases de données en quasi temps réel ou pour créer un flux d'événements pour le traitement en aval, assurant une synchronisation efficace des systèmes.

Le Change Data Feed (CDF) de Delta Lake est l'implémentation de ce concept pour les tables Delta. Il permet de suivre les modifications apportées à une table en temps réel. Les modifications sont enregistrées dans un dossier _change_data situé à côté du répertoire _delta_log. Les insertions sont calculées directement à partir du journal des transactions sans stockage séparé.

Activez le CDF et comprendre les types de changements

Pour activer le CDF, vous devez définir la propriété delta.enableChangeDataFeed à true lors de la création de la table ou via ALTER TABLEpour une table existante.

spark.sql("""
ALTER TABLE sensors_delta
SET TBLPROPERTIES (delta.enableChangeDataFeed = true)
""")

La lecture du flux de changements est similaire aux autres opérations de lecture Delta Lake, mais nécessite de spécifier l'option readChangeFeed à true. Le CDF fournit les données de ligne avec des métadonnées supplémentaires indiquant le type de changement.

Types renvoyés :

  • insert

  • delete

  • update_preimage

  • update_postimage

Ces changements peuvent être lus via des requêtes par lots ou des flux de streaming. Concrètement, ça donnerait quoi chez GreenFarm ? Vous pourriez utiliser le CDF pour propager automatiquement les mises à jour de vos données de traçabilité vers les systèmes de vos partenaires distributeurs. Chaque modification de statut de certification serait capturée et transmise en temps réel, sans avoir à rescanner l'ensemble de la table. Le CDF simplifie également vos opérations ETL en aval en traitant uniquement les changements au niveau des lignes.

Lisez le CDF en PySpark

Entre deux versions :

cdf = (spark.read.format("delta")
       .option("readChangeFeed", "true")
       .option("startingVersion", 10)
       .option("endingVersion", 11)
       .table("sensors_delta")
)
display(cdf)

 

Ou à partir d’un timestamp (pratique en production) :

cdf = (spark.read.format("delta")
       .option("readChangeFeed", "true")
       .option("startingTimestamp", "2026-01-01T00:00:00.000Z")
       .table("sensors_delta")
)
display(cdf)

Quelques mises en garde importantes : seules les modifications effectuées après l'activation du CDF sont enregistrées, vous ne pouvez pas capturer l'historique passé. Les enregistrements du CDF suivent la même politique de rétention que les fichiers de données et peuvent donc être supprimés parVACUUM

Bonne nouvelle cependant : l'activation du CDF n'ajoute pas de surcharge significative au traitement de la table, car les données de changement sont générées en ligne pendant les opérations DML et sont généralement de petite taille.

Interface d'une démo Delta Lake sur Databricks, avec le notebook
Faire l’asset Delta Lake CDF dans le Delta Lake Demo

Gérez les schémas avec flexibilité

Delta Lake applique une validation de schéma à l'écriture (schema-on-write), contrairement aux data lakes traditionnels qui utilisent une approche schema-on-read. Cette validation garantit la qualité et la cohérence des données en empêchant l'introduction de modifications incompatibles ou d'anomalies. Le schéma de la table est stocké au format JSON dans l'entrée metaData du journal des transactions, assurant une traçabilité complète.

Delta Lake permet de faire évoluer le schéma de votre table au fil du temps sans perte de données ni rupture des dépendances en aval. Vous pouvez ajouter, supprimer ou modifier des colonnes en utilisant l'option mergeSchema lors de l'écriture. Delta Lake supporte un nombre limité de conversions de types, par exemple de NullType vers tout type, ou de ByteType vers ShortType et IntegerType. Cette flexibilité contrôlée vous permet d'adapter votre schéma aux évolutions de vos besoins agricoles.

Le renommage de colonne est une opération de métadonnées uniquement qui ne nécessite pas de réécrire les fichiers sous-jacents, à condition que le column mapping soit activé. Chez GreenFarm, vous pourriez renommer "temp_sol" en "temperature_sol" pour plus de clarté sans impact sur les performances. La commande ALTER TABLE REPLACE COLUMNSpermet de remplacer l'ensemble des colonnes d'une table, mais attention : cette opération est potentiellement destructrice car elle définit toutes les valeurs des colonnes du nouveau schéma à null pour assurer la cohérence.

Enfin, la commandeREORG TABLE (Reorganize Table) permet de réorganiser une table Delta Lake en réécrivant les fichiers. Elle est notamment utilisée pour purger les données soft-deleted, c'est-à-dire les données supprimées logiquement (par exemple, suite à un  ALTER TABLE DROP COLUMN ) mais qui occupent toujours de l'espace physique. Cette opération vous permet de récupérer l'espace de stockage et d'optimiser les performances de lecture.

Félicitations ! Vous maîtrisez maintenant les fonctionnalités avancées de Delta Lake. Ces techniques vous permettent d'optimiser les performances de vos tables GreenFarm, de gérer intelligemment l'historique des données, et de suivre les modifications en temps réel. Dans le prochain chapitre, nous explorerons des cas d'usage avancés et des stratégies de gouvernance pour tirer le meilleur parti de votre Lakehouse. Bravo et continuez sur cette lancée ! 

À vous de jouer !

Contexte 

Vous allez reproduire un mini-cycle de maintenance complet, comme un data engineer GreenFarm.

Consigne 

  1. Charger le CSV et créer une table Delta partitionnée  paringest_date

  2. Simuler une croissance (générer et ajouter des lignes sur une date récente - ~100 000 lignes conseillé)

  3. Observer la fragmentation (  viaDESCRIBE DETAIL:numFiles,sizeInBytes  )

  4. Lancer  OPTIMIZE  uniquement sur les partitions récentes (  ingest_date  )

  5. Activer le CDF, faire une mise à jour + insertion, puis lire les changements

  6. Tester Time Travel (lire une version antérieure)

  7. Lancer  VACUUM   (24h) et constater l’effet

Résultat attendu : Un notebook court qui explique ce que vous avez observé avant/après optimisation.

En résumé

  • Le Data Skipping exploite les statistiques min/max automatiquement maintenues par Delta Lake pour ignorer les fichiers non pertinents, tandis que le partitionnement organise physiquement les données sur disque selon des colonnes spécifiques pour accélérer les requêtes et les opérations DML.

  • Les commandes OPTIMIZEetZORDER BYcompactent les petits fichiers et réorganisent les données avec des courbes de remplissage d'espace pour améliorer les performances, particulièrement sur les colonnes à haute cardinalité utilisées dans les prédicats de requête.

  • Le Liquid Clustering offre une alternative moderne au partitionnement traditionnel en permettant de modifier les colonnes de clustering sans réécrire la table entière, bien qu'il nécessite des versions spécifiques de runtime et soit incompatible avec le partitionnement classique.

  • Le Time Travel permet d'interroger des versions antérieures des données grâce au journal des transactions qui marque logiquement les fichiers obsolètes, tandis que VACUUM  supprime physiquement les fichiers au-delà du seuil de rétention pour optimiser les coûts de stockage.

  • Le Change Data Feed capture en temps réel les modifications (insert, update, delete) dans un dossier séparé, facilitant la synchronisation des systèmes en aval et simplifiant les opérations ETL en traitant uniquement les changements au niveau des lignes.

  • Delta Lake applique une validation de schéma à l'écriture et supporte l'évolution contrôlée du schéma (ajout, renommage, suppression de colonnes) avec des commandes comme  ALTER TABLEet REORG TABLE  pour maintenir l'intégrité des données tout en offrant la flexibilité nécessaire. 

Un Lakehouse performant ne suffit pas s’il n’est pas gouverné : il est maintenant temps de structurer l’accès aux données, d’en maîtriser les usages et d’instaurer un cadre de confiance durable pour l’ensemble de la plateforme.

Et si vous obteniez un diplôme OpenClassrooms ?
  • Formations jusqu’à 100 % financées
  • Date de début flexible
  • Projets professionnalisants
  • Mentorat individuel
Trouvez la formation et le financement faits pour vous