Delta Lake vs Apache Iceberg en 2026 : Architecture Lakehouse et Questions d'Entretien
Comparaison approfondie de Delta Lake et Apache Iceberg pour les architectures lakehouse modernes. Guide technique avec exemples de code et questions d'entretien data engineering.

Delta Lake et Apache Iceberg constituent les deux formats de table ouverts dominants qui alimentent les architectures data lakehouse modernes en 2026. Ces deux technologies résolvent le même problème fondamental—apporter les transactions ACID, l'évolution de schéma et le voyage dans le temps au stockage objet cloud—mais adoptent des approches architecturales différentes qui importent pour les charges de travail en production.
Delta Lake excelle dans les environnements natifs Spark avec une intégration étroite à Databricks, tandis qu'Iceberg offre une compatibilité moteur plus large (Spark, Trino, Flink, Dremio) et un partitionnement plus flexible grâce aux partitions cachées et à l'évolution des partitions.
Delta Lake vs Iceberg : Différences Architecturales Fondamentales
Les deux formats stockent les données sous forme de fichiers Parquet sur le stockage objet, mais leurs couches de métadonnées diffèrent significativement.
Delta Lake utilise un journal de transactions (_delta_log/) contenant des fichiers JSON qui enregistrent chaque modification. Chaque commit crée un nouveau fichier JSON, et des points de contrôle périodiques consolident ces fichiers en Parquet pour des lectures plus rapides. La spécification du protocole Delta Lake définit des fonctionnalités de lecture/écriture versionnées pour la compatibilité ascendante.
Apache Iceberg maintient une hiérarchie de fichiers de métadonnées : un fichier JSON de métadonnées pointant vers des listes de manifestes, qui pointent vers des manifestes contenant des statistiques au niveau des fichiers. Cette conception permet le predicate pushdown dès l'étape de planification—le moteur de requêtes ignore des fichiers entiers avant de lire des données.
| Fonctionnalité | Delta Lake | Apache Iceberg | |----------------|------------|----------------| | Journal de Transactions | JSON + checkpoints Parquet | JSON métadonnées + fichiers manifestes | | Évolution des Partitions | Nécessite réécriture | En place sans réécriture | | Support Moteurs | Spark, Trino, Flink | Spark, Trino, Flink, Dremio, Athena | | Voyage dans le Temps | Basé sur les versions | Basé sur les snapshots avec branch/tag | | Évolution de Schéma | Ajout/renommage colonnes | Ajout/renommage/réordonnancement/élargissement colonnes |
Partitions Cachées : L'Avantage Clé d'Iceberg
Le partitionnement traditionnel style Hive expose les colonnes de partition dans les requêtes (WHERE year=2026 AND month=7), couplant la disposition physique à la syntaxe SQL. Les partitions cachées d'Iceberg découplent ces préoccupations.
# iceberg_partition_example.py
from pyiceberg.catalog import load_catalog
from pyiceberg.schema import Schema
from pyiceberg.types import StringType, TimestampType, LongType, NestedField
from pyiceberg.partitioning import PartitionSpec, PartitionField
from pyiceberg.transforms import MonthTransform
# Définition du schéma
schema = Schema(
NestedField(1, "event_id", LongType(), required=True),
NestedField(2, "event_time", TimestampType(), required=True),
NestedField(3, "user_id", StringType(), required=True),
NestedField(4, "event_type", StringType(), required=False),
)
# Partition cachée sur le mois extrait de event_time
partition_spec = PartitionSpec(
PartitionField(
source_id=2, # champ event_time
field_id=1000,
transform=MonthTransform(),
name="event_time_month"
)
)
# Création de la table avec partitionnement caché
catalog = load_catalog("production")
catalog.create_table(
identifier="analytics.events",
schema=schema,
partition_spec=partition_spec
)Les utilisateurs écrivent WHERE event_time > '2026-01-01' et Iceberg élimine automatiquement les partitions. Cette approche simplifie les requêtes et permet l'évolution des partitions sans réécriture des données.
Delta Lake : Gestion du Journal de Transactions
Le mécanisme de journal de transactions de Delta Lake fournit une traçabilité complète des modifications. Chaque opération génère un fichier JSON atomique dans le répertoire _delta_log.
# delta_transaction_log.py
from delta import DeltaTable
from pyspark.sql import SparkSession
spark = SparkSession.builder \
.appName("DeltaTransactionDemo") \
.config("spark.sql.extensions", "io.delta.sql.DeltaSparkSessionExtension") \
.config("spark.sql.catalog.spark_catalog", "org.apache.spark.sql.delta.catalog.DeltaCatalog") \
.getOrCreate()
# Création d'une table Delta
data = [(1, "2026-07-15", "click"), (2, "2026-07-16", "purchase")]
df = spark.createDataFrame(data, ["id", "date", "event"])
df.write.format("delta").save("/data/events")
# Accès à l'historique des transactions
delta_table = DeltaTable.forPath(spark, "/data/events")
history = delta_table.history()
history.select("version", "timestamp", "operation", "operationMetrics").show()Les checkpoints Parquet se créent tous les 10 commits par défaut, optimisant les performances de lecture en évitant la reconstruction de l'état à partir de nombreux fichiers JSON.
Évolution de Schéma : Comparaison Pratique
L'évolution de schéma représente un cas d'usage critique pour les pipelines de données en production. Les deux formats supportent l'ajout de colonnes, mais Iceberg offre des capacités plus avancées.
-- Évolution de schéma Iceberg
ALTER TABLE analytics.events ADD COLUMN device_type STRING;
ALTER TABLE analytics.events ALTER COLUMN event_type SET NOT NULL;
ALTER TABLE analytics.events RENAME COLUMN event_type TO action_type;
-- Réordonnancement des colonnes (spécifique à Iceberg)
ALTER TABLE analytics.events ALTER COLUMN device_type FIRST;
ALTER TABLE analytics.events ALTER COLUMN user_id AFTER event_id;-- Évolution de schéma Delta Lake
ALTER TABLE events ADD COLUMNS (device_type STRING);
-- Le renommage nécessite l'activation de column mapping
ALTER TABLE events SET TBLPROPERTIES ('delta.columnMapping.mode' = 'name');
ALTER TABLE events RENAME COLUMN event_type TO action_type;Delta Lake requiert l'activation explicite du column mapping pour le renommage, tandis qu'Iceberg le supporte nativement via son système d'identifiants de champs.
Voyage dans le Temps et Gestion des Versions
Les deux formats permettent d'interroger des états historiques des données, fonctionnalité essentielle pour l'audit, le débogage et la reproductibilité des analyses.
# time_travel_comparison.py
# Delta Lake - Voyage dans le temps
df_v1 = spark.read.format("delta").option("versionAsOf", 1).load("/data/events")
df_timestamp = spark.read.format("delta").option("timestampAsOf", "2026-07-15").load("/data/events")
# Restauration d'une version précédente
delta_table = DeltaTable.forPath(spark, "/data/events")
delta_table.restoreToVersion(1)# Iceberg - Voyage dans le temps avec snapshots
from pyiceberg.catalog import load_catalog
catalog = load_catalog("production")
table = catalog.load_table("analytics.events")
# Liste des snapshots disponibles
for snapshot in table.snapshots():
print(f"Snapshot {snapshot.snapshot_id}: {snapshot.timestamp_ms}")
# Lecture d'un snapshot spécifique
df = spark.read \
.format("iceberg") \
.option("snapshot-id", 3821550127947089987) \
.load("analytics.events")
# Branches et tags Iceberg (fonctionnalité avancée)
# CREATE TAG production_v1 FOR TABLE analytics.events
# CREATE BRANCH feature_test FOR TABLE analytics.eventsIceberg offre des fonctionnalités supplémentaires avec les branches et tags, permettant des workflows de développement isolés sans dupliquer les données.
Optimisation et Maintenance des Tables
Les opérations de maintenance sont cruciales pour maintenir les performances des tables lakehouse au fil du temps.
# delta_optimization.py
from delta.tables import DeltaTable
delta_table = DeltaTable.forPath(spark, "/data/events")
# Compaction des petits fichiers
delta_table.optimize().executeCompaction()
# Z-Ordering pour améliorer le data skipping
delta_table.optimize().executeZOrderBy("user_id", "event_time")
# Vacuum pour supprimer les fichiers obsolètes
delta_table.vacuum(168) # Rétention de 7 jours en heures
# Statistiques des colonnes
spark.sql("ANALYZE TABLE events COMPUTE STATISTICS FOR ALL COLUMNS")# iceberg_maintenance.py
# Compaction Iceberg via Spark
spark.sql("""
CALL system.rewrite_data_files(
table => 'analytics.events',
options => map('target-file-size-bytes', '134217728')
)
""")
# Expiration des snapshots
spark.sql("""
CALL system.expire_snapshots(
table => 'analytics.events',
older_than => TIMESTAMP '2026-07-01 00:00:00',
retain_last => 5
)
""")
# Suppression des fichiers orphelins
spark.sql("""
CALL system.remove_orphan_files(
table => 'analytics.events',
older_than => TIMESTAMP '2026-07-01 00:00:00'
)
""")Questions d'Entretien Data Engineering : Lakehouse Architecture
Les entretiens data engineering en 2026 incluent fréquemment des questions sur les architectures lakehouse. Voici les thèmes techniques essentiels à maîtriser.
Question 1 : Expliquer les avantages des partitions cachées d'Iceberg
La réponse attendue doit couvrir : le découplage entre la disposition physique et la syntaxe SQL, l'élimination automatique des partitions par le moteur de requêtes, et la possibilité d'évoluer le schéma de partitionnement sans réécrire les données existantes.
Question 2 : Comment Delta Lake garantit-il les transactions ACID ?
Delta Lake utilise le verrouillage optimiste avec un journal de transactions append-only. Chaque commit vérifie que la version de base n'a pas changé depuis la lecture. En cas de conflit, l'opération échoue et peut être réessayée. Les checkpoints Parquet permettent une reconstruction rapide de l'état.
Question 3 : Quand choisir Iceberg plutôt que Delta Lake ?
Iceberg convient mieux lorsque : plusieurs moteurs de requêtes doivent accéder aux mêmes données (Spark, Trino, Flink), l'évolution des partitions est un besoin récurrent, ou l'organisation préfère un format véritablement ouvert sans dépendance à un fournisseur spécifique.
# interview_code_example.py
# Question : Implémenter une upsert avec Delta Lake
from delta.tables import DeltaTable
def upsert_events(spark, source_df, target_path):
"""Merge incremental events into Delta table."""
target_table = DeltaTable.forPath(spark, target_path)
target_table.alias("target").merge(
source_df.alias("source"),
"target.event_id = source.event_id"
).whenMatchedUpdate(set={
"event_time": "source.event_time",
"event_type": "source.event_type",
"updated_at": "current_timestamp()"
}).whenNotMatchedInsert(values={
"event_id": "source.event_id",
"event_time": "source.event_time",
"event_type": "source.event_type",
"created_at": "current_timestamp()",
"updated_at": "current_timestamp()"
}).execute()Question 4 : Décrire la stratégie de data skipping
Les deux formats maintiennent des statistiques min/max par fichier. Lors de l'exécution d'une requête avec prédicats, le moteur compare les valeurs des prédicats aux statistiques et élimine les fichiers qui ne peuvent pas contenir de correspondances. Le Z-Ordering (Delta) et le sorting (Iceberg) améliorent l'efficacité en regroupant les valeurs similaires.
Prêt à réussir tes entretiens Data Engineering ?
Entraîne-toi avec nos simulateurs interactifs, fiches express et tests techniques.
Intégration avec les Catalogues de Métadonnées
Les catalogues de métadonnées centralisent la gestion des tables lakehouse et permettent la découverte des données à l'échelle de l'organisation.
# catalog_integration.py
# Configuration Unity Catalog pour Delta Lake
spark = SparkSession.builder \
.config("spark.sql.catalog.unity", "com.databricks.sql.managedcatalog.UnityCatalogSpark") \
.config("spark.databricks.unityCatalog.enabled", "true") \
.getOrCreate()
# Configuration Iceberg avec AWS Glue Catalog
spark = SparkSession.builder \
.config("spark.sql.catalog.glue_catalog", "org.apache.iceberg.spark.SparkCatalog") \
.config("spark.sql.catalog.glue_catalog.warehouse", "s3://datalake/warehouse") \
.config("spark.sql.catalog.glue_catalog.catalog-impl", "org.apache.iceberg.aws.glue.GlueCatalog") \
.config("spark.sql.catalog.glue_catalog.io-impl", "org.apache.iceberg.aws.s3.S3FileIO") \
.getOrCreate()
# Configuration Iceberg avec REST Catalog (Polaris, Tabular)
spark = SparkSession.builder \
.config("spark.sql.catalog.rest_catalog", "org.apache.iceberg.spark.SparkCatalog") \
.config("spark.sql.catalog.rest_catalog.type", "rest") \
.config("spark.sql.catalog.rest_catalog.uri", "https://catalog.example.com") \
.getOrCreate()Performance : Benchmarks et Considérations
Les performances dépendent fortement du cas d'usage spécifique, de la taille des données et du moteur de requêtes utilisé.
Pour les lectures analytiques intensives, Iceberg peut offrir un avantage grâce à sa planification de requêtes plus efficace basée sur les manifestes. Pour les workloads streaming avec micro-batches fréquents, Delta Lake avec son journal de transactions optimisé peut être plus performant.
# performance_monitoring.py
# Métriques Delta Lake
spark.sql("DESCRIBE HISTORY events").show()
spark.sql("DESCRIBE DETAIL events").show()
# Métriques Iceberg
spark.sql("SELECT * FROM analytics.events.metadata_log_entries").show()
spark.sql("SELECT * FROM analytics.events.manifests").show()
spark.sql("SELECT * FROM analytics.events.files").show()Conclusion
Delta Lake et Apache Iceberg représentent deux approches matures pour l'architecture lakehouse en 2026. Delta Lake offre une intégration native avec l'écosystème Databricks et Spark, tandis qu'Iceberg privilégie l'interopérabilité multi-moteurs et la flexibilité du partitionnement.
Le choix entre ces technologies dépend principalement de l'écosystème existant, des exigences d'interopérabilité et des patterns d'accès aux données. Les deux formats continuent d'évoluer avec des fonctionnalités convergentes, comme Delta Lake UniForm qui permet la lecture des tables Delta via les APIs Iceberg.
Pour les entretiens data engineering, la maîtrise des concepts fondamentaux—transactions ACID sur stockage objet, évolution de schéma, voyage dans le temps et optimisation des performances—reste plus importante que la connaissance approfondie d'un format spécifique.
Partager
Articles similaires

Snowflake en 2026 : architecture, SQL et questions d'entretien data engineer
Un guide 2026 de l'architecture Snowflake pour data engineers : comment le stockage et le calcul se séparent, comment fonctionnent les virtual warehouses et les micro-partitions, et les questions d'entretien qui testent l'expérience en production.

Apache Airflow en 2026 : orchestration de pipelines, DAG et questions d'entretien
Maîtriser Apache Airflow 3.2 avec ce tutoriel pratique : écriture de DAG avec le Task SDK, patterns d'orchestration de pipelines, partitions d'assets et vraies questions d'entretien pour les postes de data engineering en 2026.

dbt en 2026 : transformations de données, tests et questions d'entretien
Tutoriel pratique sur dbt (data build tool) : transformations SQL, modélisation par couches, stratégies de test et vraies questions d'entretien pour les postes de data engineering en 2026.