AccueilBlogTest technique Apache Iceberg avancé : catalog, time travel, merge-on-read
Guide recrutement data

Test technique Apache Iceberg avancé : catalog, time travel, merge-on-read

Iceberg est devenu le standard ouvert pour les tables lakehouse. En entretien Expert, on évalue la maîtrise des fonctionnalités avancées : catalog REST, partition evolution, et les stratégies d écriture.

Data Builder·Juin 2025·7 min de lecture·Data Engineer
Sommaire
  1. Iceberg Catalog
  2. Partition Evolution
  3. Time Travel avancé
  4. Copy-on-Write vs Merge-on-Read
  5. Maintenance de tables
  6. Interopérabilité multi-engine
  7. Grille

1Iceberg Catalog : l abstraction de gouvernance

Question discriminante

Qu est-ce qu un Iceberg Catalog ? Pourquoi est-il central dans une architecture Lakehouse ?

## Types de catalogs Iceberg # 1. REST Catalog (standard émergent 2025) # Serveur HTTP qui expose l API Iceberg REST # Compatible avec tous les engines (Spark, Trino, Flink, DuckDB) spark = SparkSession.builder \ .config('spark.sql.catalog.prod', 'org.apache.iceberg.spark.SparkCatalog') \ .config('spark.sql.catalog.prod.catalog-impl', 'org.apache.iceberg.rest.RESTCatalog') \ .config('spark.sql.catalog.prod.uri', 'https://iceberg-catalog.monentreprise.com') \ .getOrCreate() # 2. AWS Glue Catalog (managé AWS) .config('spark.sql.catalog.glue.catalog-impl', 'org.apache.iceberg.aws.glue.GlueCatalog') # 3. Nessie (versioning Git-like pour le catalog) .config('spark.sql.catalog.nessie.catalog-impl', 'org.projectnessie.iceberg.NessieCatalog')

2Partition Evolution : changer sans réécrire

Question discriminante

Qu est-ce que la partition evolution ? Pourquoi est-ce un avantage majeur d Iceberg sur Hive ?

from pyiceberg.catalog import load_catalog from pyiceberg.transforms import MonthTransform, DayTransform catalog = load_catalog('prod') table = catalog.load_table('analytics.orders') # Partition Evolution : changer le schéma de partition # sans réécrire les données existantes with table.update_spec() as update: # Avant : partitionné par mois # Après : partitionner par jour (pour les nouvelles partitions) update.remove_field('order_month') # supprimer l ancienne update.add_identity('order_date') # ajouter la nouvelle # Les anciennes données restent dans leurs partitions par mois # Les nouvelles données vont dans des partitions par jour # Iceberg gère la coexistence automatiquement # Avec Hive : impossible sans réécrire toutes les données !

3Time Travel avancé

Question discriminante

Comment requêtez-vous l état d une table Iceberg à un snapshot précis ?

-- Time Travel par timestamp SELECT * FROM prod.analytics.orders FOR SYSTEM_TIME AS OF '2025-01-15 08:00:00'; -- Time Travel par snapshot ID SELECT * FROM prod.analytics.orders FOR VERSION AS OF 1234567890; -- Lister les snapshots disponibles SELECT * FROM prod.analytics.orders.snapshots ORDER BY committed_at DESC LIMIT 10; -- Comparer deux snapshots (identifier ce qui a changé) SELECT * FROM prod.analytics.orders.changes BETWEEN TIMESTAMP '2025-01-14 00:00:00' AND TIMESTAMP '2025-01-15 00:00:00'; -- Rollback vers un état précédent CALL prod.system.rollback_to_timestamp( 'analytics.orders', TIMESTAMP '2025-01-14 12:00:00' );

4Copy-on-Write vs Merge-on-Read

Question discriminante

Quelle est la différence entre CoW et MoR ? Quand choisissez-vous l un ou l autre ?

Copy-on-Write (CoW)Merge-on-Read (MoR)
ÉcritureRéécriture des fichiers impactésÉcriture dans des fichiers delta (positional deletes)
LectureLecture directe, fichiers propresMerge à la lecture (fichiers data + deletes)
Coût écritureÉlevé (I/O)Faible
Coût lectureFaiblePotentiellement élevé (sans compaction)
Idéal pourLectures fréquentes, écritures raresMises à jour fréquentes (CDC), écritures intensives

5Maintenance des tables Iceberg

Question discriminante

Quelles opérations de maintenance planifiez-vous sur vos tables Iceberg ?

## Opérations de maintenance (scheduler via Airflow) # 1. Compaction : fusionner les petits fichiers SPARK.sql(""" CALL prod.system.rewrite_data_files( table => 'analytics.orders', strategy => 'sort', sort_order => 'order_date, region', options => map('min-input-files', '5', 'target-file-size-bytes', '134217728') ) """) # 2. Expirer les anciens snapshots SPARK.sql(""" CALL prod.system.expire_snapshots( table => 'analytics.orders', older_than => TIMESTAMP '2024-12-01 00:00:00', retain_last => 3 ) """) # 3. Supprimer les fichiers orphelins SPARK.sql(""" CALL prod.system.remove_orphan_files( table => 'analytics.orders', dry_run => false ) """)

6Interopérabilité : Spark + Trino + DuckDB

Question discriminante

Comment faites-vous cohabiter plusieurs engines sur les mêmes tables Iceberg ?

## Trino + Iceberg : SQL OLAP performant CREATE TABLE iceberg.analytics.orders ( order_id VARCHAR, amount DOUBLE, order_date DATE ) WITH ( format = 'PARQUET', partitioning = ARRAY['month(order_date)'], sorted_by = ARRAY['order_date'] ); ## DuckDB + Iceberg (v0.10+) INSTALL iceberg; LOAD iceberg; SELECT * FROM iceberg_scan( 's3://mon-bucket/warehouse/analytics/orders', allow_moved_paths = true ); ## Règle de cohabitation : # Lire depuis tous les engines # Écrire depuis 1 seul engine à la fois (pas de concurrent writes) # Sauf Iceberg Multi-Writer (optimistic locking)

7Grille par niveau

NiveauMaitriseSignal GONO-GO
ConfirméTables Iceberg basiques, time travel, catalogsA créé des tables Iceberg, utilise le time travel, comprend les catalogsNe sait pas la différence entre Iceberg et un simple Parquet
SeniorPartition evolution, CoW vs MoR, maintenance planifiéeA fait une partition evolution, choisit CoW vs MoR selon le cas, planifie la compactionNe sait pas ce qu est la partition evolution

Vous recrutez un Data Engineer Iceberg Expert ?

Premier entretien gratuit. Rapport GO/NO-GO sous 48h.