Apache Beam vs Spark en 2026 : Pipelines Unifiés et Questions d'Entretien

Comparaison détaillée entre Apache Beam et Spark pour les pipelines de données en 2026. Portabilité, windowing, performances et questions d'entretien techniques.

Apache Beam vs Spark comparison 2026

Apache Beam et Spark représentent deux approches fondamentalement différentes pour le traitement de données à grande échelle. Beam 2.76 (août 2026) et Spark 4.2 (juillet 2026) gèrent tous deux les workloads batch et streaming, mais leurs philosophies de conception divergent : Beam abstrait le moteur d'exécution tandis que Spark fournit un runtime étroitement intégré.

Framework de Décision Rapide

Choisir Beam lorsque la portabilité entre runners (Dataflow, Flink, Spark) est importante ou lors de l'utilisation de Google Cloud Dataflow. Choisir Spark pour les clusters auto-gérés, Databricks, ou l'intégration ML avec MLlib.

Modèle de Portabilité Beam vs Moteur Unifié Spark

Apache Beam sépare le modèle de programmation de l'exécution. Une définition de pipeline unique s'exécute sur Google Cloud Dataflow, Apache Flink, Apache Spark, ou d'autres runners sans modification de code. Cette abstraction provient du SDK Beam qui génère une représentation portable du pipeline que tout runner compatible interprète.

Spark 4.2 adopte l'approche inverse. L'API DataFrame, Structured Streaming et MLlib partagent le même optimiseur Catalyst et le moteur d'exécution Tungsten. Ce couplage étroit permet des optimisations comme Adaptive Query Execution qui ajuste les plans à l'exécution selon les statistiques réelles des données.

python
# beam_pipeline.py
import apache_beam as beam
from apache_beam.options.pipeline_options import PipelineOptions

# Le même code s'exécute sur Dataflow, Flink, ou Spark runner
options = PipelineOptions([
    '--runner=DataflowRunner',  # Basculer vers FlinkRunner ou SparkRunner
    '--project=my-project',
    '--region=us-central1',
    '--temp_location=gs://my-bucket/temp'
])

with beam.Pipeline(options=options) as pipeline:
    (pipeline
     | 'ReadEvents' >> beam.io.ReadFromPubSub(topic='projects/p/topics/events')
     | 'ParseJSON' >> beam.Map(lambda x: json.loads(x))
     | 'FilterValid' >> beam.Filter(lambda e: e.get('status') == 'valid')
     | 'WindowByMinute' >> beam.WindowInto(beam.window.FixedWindows(60))
     | 'CountPerWindow' >> beam.combiners.Count.Globally()
     | 'WriteToBQ' >> beam.io.WriteToBigQuery('project:dataset.table'))

L'équivalent Spark est directement lié au runtime Spark :

python
# spark_streaming.py
from pyspark.sql import SparkSession
from pyspark.sql.functions import from_json, col, window

spark = SparkSession.builder \
    .appName("EventProcessing") \
    .config("spark.sql.adaptive.enabled", "true") \
    .getOrCreate()

# Spark 4.2 : Mode ANSI activé par défaut, vérification de types plus stricte
events = spark.readStream \
    .format("kafka") \
    .option("kafka.bootstrap.servers", "broker:9092") \
    .option("subscribe", "events") \
    .load()

processed = events \
    .select(from_json(col("value").cast("string"), schema).alias("data")) \
    .filter(col("data.status") == "valid") \
    .groupBy(window(col("data.timestamp"), "1 minute")) \
    .count()

processed.writeStream \
    .format("bigquery") \
    .option("table", "project.dataset.table") \
    .outputMode("append") \
    .start()

La portabilité de Beam permet des architectures cloud-agnostiques mais ajoute une couche de traduction. L'exécution directe de Spark montre généralement une latence plus faible pour des opérations équivalentes sur le même matériel.

Windowing et Traitement Event-Time Comparés

Les deux frameworks gèrent la sémantique event-time, mais leurs APIs reflètent des héritages différents. Le modèle de windowing de Beam provient du Dataflow Model paper (2015), traitant les windows comme des éléments de pipeline de première classe. Spark a adapté son windowing pour Structured Streaming, l'intégrant avec l'API DataFrame.

FonctionnalitéBeam 2.76Spark 4.2
Fixed windowsFixedWindows(duration)window(col, duration)
Sliding windowsSlidingWindows(size, period)window(col, size, period)
Session windowsSessions(gap)Non natif (flatMapGroupsWithState)
Custom windowsSous-classe WindowFnLimité
Late data handlingTriggers intégrésDélais de watermark
Allowed latenessConfiguration par windowWatermark global

Les session windows révèlent le mieux la différence. Beam traite les sessions comme une stratégie de windowing native :

python
# beam_sessions.py
from apache_beam import window

# 30 minutes de gap de session, accepte 1 heure de données en retard
windowed = (
    events
    | 'SessionWindow' >> beam.WindowInto(
        window.Sessions(30 * 60),  # 30 min de gap ferme la session
        trigger=beam.trigger.AfterWatermark(
            early=beam.trigger.AfterProcessingTime(60),
            late=beam.trigger.AfterCount(1)
        ),
        allowed_lateness=3600,  # Accepte les données jusqu'à 1 heure en retard
        accumulation_mode=beam.trigger.AccumulationMode.ACCUMULATING
    )
)

Spark nécessite un traitement stateful pour les sessions :

python
# spark_sessions.py
from pyspark.sql.streaming import GroupState, GroupStateTimeout

def update_session(key, events, state: GroupState):
    # Gestion manuelle des sessions avec l'API state
    session_data = state.getOption() or {"count": 0, "start": None, "end": None}
    
    for event in events:
        ts = event.timestamp
        if session_data["end"] and (ts - session_data["end"]).seconds > 1800:
            # Gap dépassé 30 min, émettre la session précédente
            yield session_data
            session_data = {"count": 0, "start": ts, "end": ts}
        
        session_data["count"] += 1
        session_data["end"] = ts
        if not session_data["start"]:
            session_data["start"] = ts
    
    state.update(session_data)
    state.setTimeoutDuration(30 * 60 * 1000)  # 30 min timeout

# Spark 4.2 Arbitrary State API v2
result = events \
    .groupByKey(lambda e: e.user_id) \
    .flatMapGroupsWithState(
        update_session,
        outputMode="append",
        stateType=session_schema,
        timeoutConf=GroupStateTimeout.ProcessingTimeTimeout
    )

Pour la préparation aux entretiens sur ces sujets, consulter le module Questions d'entretien Apache Beam et Dataflow.

Performances : Données de Benchmark 2026

Les comparaisons directes nécessitent une configuration soignée puisque Beam s'exécute sur Spark comme option de runner. La comparaison pertinente oppose Beam-on-Dataflow à Spark natif.

Les benchmarks récents de Databricks et Google Cloud montrent :

WorkloadSpark 4.2 (Databricks)Beam 2.76 (Dataflow)Notes
Batch ETL (1TB Parquet)4.2 min5.1 minAvantage du moteur Photon de Spark
Streaming (100K events/sec)45ms p99 latence120ms p99 latenceOverhead d'autoscaling Dataflow
Exactly-once sink writesNatifNatifLes deux supportent depuis 2024
Coût (workload soutenu)$0.12/GB traité$0.08/GB traitéTarification Dataflow Flex

Les gains de performance de Spark 4.2 proviennent de plusieurs fonctionnalités :

  • Mode ANSI par défaut : sémantique SQL plus stricte détecte les erreurs plus tôt
  • Type de données VARIANT : gestion native des données semi-structurées
  • Adaptive Query Execution : optimisation du plan à l'exécution
  • Support Java 21 : les virtual threads réduisent l'overhead

Beam 2.76 contre avec :

  • Support Flink 2.0 runner : streaming stateful de niveau production
  • Persistance des offsets CDC : DebeziumIO FileSystemOffsetRetainer
  • Intégration ADK : support Google Agent Development Kit dans le SDK Python

Prêt à réussir tes entretiens Data Engineering ?

Entraîne-toi avec nos simulateurs interactifs, fiches express et tests techniques.

Questions d'Entretien Courantes : Beam vs Spark

Les entretiens techniques pour les postes de data engineering comparent fréquemment ces frameworks. Voici les questions qui apparaissent dans les entretiens de 2026, avec la profondeur de réponse attendue.

Q1 : Quand choisir Beam plutôt que Spark natif ?

Points de réponse attendus :

  • Déploiements multi-cloud ou hybrides où le code du pipeline doit s'exécuter sans modification
  • Environnements Google Cloud où Dataflow fournit une infrastructure gérée
  • Sémantique event-time complexe nécessitant des session windows ou des triggers personnalisés
  • Équipes avec une expertise Beam existante issue d'un background Dataflow

Réponse red flag : "Beam est toujours meilleur parce qu'il est portable." La portabilité a des coûts d'overhead.

Q2 : Comment l'abstraction du runner de Beam affecte-t-elle le débogage ?

Points de réponse attendus :

  • Les stack traces référencent à la fois le SDK Beam et l'implémentation du runner
  • Les optimisations spécifiques au runner peuvent se comporter différemment (checkpoints Flink vs checkpoints Spark)
  • L'API Metrics fournit un monitoring unifié, mais les dashboards des runners montrent des détails différents
  • Tester avec DirectRunner avant de déployer sur le runner de production

Q3 : Expliquer la sémantique exactly-once dans les deux frameworks.

Réponse attendue :

python
# Beam : exactly-once via les garanties du runner
# Dataflow fournit exactly-once pour les sources et les sinks
# Le SDK gère la déduplication et la coordination des checkpoints

with beam.Pipeline() as p:
    (p
     | beam.io.ReadFromPubSub(subscription='...')  # Lecture exactly-once
     | beam.Map(process)
     | beam.io.WriteToBigQuery(...)  # Écriture exactly-once avec retries
    )

# Spark : exactly-once via checkpointing et sinks idempotents
spark.readStream \
    .format("kafka") \
    .load() \
    .writeStream \
    .option("checkpointLocation", "/checkpoint")  # Récupération d'état
    .foreachBatch(idempotent_write)  # Déduplication niveau application
    .start()

Pour plus de sujets d'entretien sur le streaming, consulter le module PySpark.

Q4 : Comment migrer un job batch Spark vers Beam ?

Cette question teste la compréhension des deux APIs. Points clés :

  1. Mapper les opérations DataFrame vers les PCollections et transforms
  2. Remplacer spark.read par les connecteurs I/O Beam appropriés
  3. Convertir les UDFs en fonctions beam.Map ou beam.ParDo
  4. Gérer le partitionnement différemment (Reshuffle de Beam vs repartition de Spark)
  5. Tester avec DirectRunner avant de déployer sur le runner de production

Choisir le Bon Outil : Matrice de Décision

Le choix dépend davantage du contexte organisationnel que des capacités techniques. Les deux frameworks gèrent la plupart des workloads de data engineering de manière compétente.

FacteurFavorise BeamFavorise Spark
Cloud providerGoogle CloudAWS EMR, Databricks, on-prem
Expertise équipeExpérience Dataflow existanteCompétences Spark/PySpark existantes
Intégration MLLimitée (outils séparés)MLlib, Spark ML
Analyse interactiveNon conçu pour celaSpark SQL, notebooks
Session windowsSupport natifGestion manuelle de l'état
Modèle de coûtPay-per-use (Dataflow)Provisionnement de cluster
Vendor lock-inPlus faible (multiples runners)Plus élevé (code Spark-spécifique)

Pour les décisions sur les patterns ETL/ELT, considérer le volume de données et les exigences de latence avant de sélectionner un framework.

Architecture Réelle : Approche Hybride

De nombreuses organisations utilisent les deux frameworks. Un pattern courant :

text
[Ingestion Streaming]     [Traitement Batch]     [Entraînement ML]
        |                        |                    |
   Beam/Dataflow           Spark sur Databricks    Spark MLlib
        |                        |                    |
        v                        v                    v
    BigQuery  <----- dbt -----> Delta Lake -----> Model Registry

Beam gère l'ingestion streaming où l'autoscaling de Dataflow correspond aux patterns de trafic. Spark traite les workloads batch où l'économie des clusters favorise un compute soutenu. Les deux alimentent un data warehouse unifié.

Cette architecture apparaît dans le tutoriel Apache Spark avec des détails d'implémentation.

Passe à la pratique !

Teste tes connaissances avec nos simulateurs d'entretien et tests techniques.

Points Clés pour la Sélection Beam vs Spark

  • Beam 2.76 fournit la portabilité des runners sur Dataflow, Flink 2.0 et Spark, échangeant des performances contre une flexibilité de déploiement
  • Spark 4.2 offre une intégration plus étroite entre SQL, streaming et workloads ML avec des fonctionnalités comme les types VARIANT et Adaptive Query Execution
  • Les session windows et triggers complexes favorisent le modèle de windowing natif de Beam
  • Les performances batch sur un matériel équivalent favorisent généralement Spark grâce à l'optimisation Catalyst/Tungsten
  • Les questions d'entretien se concentrent sur les compromis plutôt que de déclarer un framework supérieur
  • Les architectures hybrides utilisant les deux frameworks sont courantes en environnement de production
  • La comparaison des coûts dépend des patterns de workload : tarification par GB de Dataflow vs provisionnement de cluster Spark
Défi du jour

Tu saurais repérer le bug en Data Engineering ?

Un vrai bout de code, un bug caché, une tentative par jour. Sans compte pour essayer.

Anthony Fillion-Maillet

Écrit par

Anthony Fillion-Maillet

Fondateur de SharpSkill

Développeur fullstack depuis plus de 10 ans. Il dirige SharpSkill et répond de tout ce qui y est publié.

Mis à jour le 10 septembre 2026

Tags

#apache-beam
#spark
#data-engineering
#dataflow
#streaming

Partager

Articles similaires