Inhaltsverzeichnis19 Abschnitte
- TL;DR
- Was ist Event-Driven Data Architecture?
- Kernkonzepte
- Event Sourcing
- CQRS — Command Query Responsibility Segregation
- Apache Kafka als Backbone
- Eine Event-Driven Data-Pipeline bauen
- 1. Event-Schema-Design
- 2. Kafka Producer (Python)
- 3. Stream Processing mit Flink / Spark Structured Streaming
- Event-Driven Patterns für Data-Plattformen
- Outbox Pattern
- Event-Driven Feature Store
- Saga Pattern für verteilte Transaktionen
- Trade-offs ehrlich gesagt
- Wann Event-Driven für Daten einsetzen
- FAQ
- Fazit
- Weiterlesen
Batch-Jobs laufen um Mitternacht und produzieren Daten, die 12 Stunden alt sind, sobald sie jemand liest. Deine Kunden treffen Entscheidungen aber in Echtzeit — sie kaufen, kündigen, klicken. Event-Driven Data Architecture ist das Pattern, das diese Lücke schließt: Daten fließen, wenn Events passieren, nicht nach Zeitplan.
TL;DR
- Event-Driven bedeutet: jede Zustandsänderung wird als unveränderbares Event protokolliert
- Event Sourcing leitet aktuellen Zustand aus Replay des Event-Logs ab — perfekter Audit-Trail
- CQRS trennt Write-Path (Commands) von Read-Path (vorberechnete Read-Modelle)
- Kafka ist das Standard-Backbone für persistente, replayable Event-Logs
- Trade-off: real-time hat hohe Komplexität — wenn Batch ausreicht, bleib bei Batch
Was ist Event-Driven Data Architecture?
In einer Event-Driven-Architektur wird jede relevante Zustandsänderung als
unveränderbares Event aufgezeichnet: OrderPlaced, UserSignedUp,
PaymentFailed, InventoryUpdated. Diese Events fließen durch einen Message
Broker (meist Apache Kafka) und werden von mehreren Downstream-Systemen
unabhängig konsumiert.
Konkret für Data-Plattformen heißt das:
- Dein Warehouse konsumiert Events und aktualisiert Tabellen near-real-time
- ML-Modelle reagieren auf Events, ohne eine Datenbank zu pollen
- Operational- und Analytics-Systeme teilen sich denselben Event-Stream
- Historischer Zustand lässt sich durch Replay des Event-Logs rekonstruieren
Application Services
│ emits events
▼
Apache Kafka (Event Log)
│
┌────┴─────────────────────────────────┐
│ │ │ │
▼ ▼ ▼ ▼
Warehouse ML Feature Search Notification
(Flink/ Store Index Service
Spark) (Redis/Feast) (ES) (SendGrid)
Kernkonzepte
Event Sourcing
Event Sourcing heißt: der Zustand deiner Anwendung wird aus einem
append-only Log von Events abgeleitet — nicht aus einer veränderbaren
Datenbank-Tabelle. Statt eine Zeile zu aktualisieren
(UPDATE orders SET status = 'shipped'), hängst du ein Event an
(OrderShipped { order_id, shipped_at, carrier }).
Der aktuelle Zustand einer Entität wird durch Replay aller Events für diese Entität berechnet.
Vorteile für Daten-Teams:
- Perfekter Audit-Trail — jede Zustandsänderung mit Timestamp und Actor
- Time Travel ist natürlich — Replay bis zu jedem Zeitpunkt
- Schema-Evolution ist explizit — neue Event-Typen brechen alte Consumer nicht
- Derived Tables von Grund auf neu aufbauen ist immer möglich
Der Preis: Millionen Events zu replayen, um aktuellen Zustand zu bekommen, ist langsam. Du brauchst Snapshots (periodische Zustands-Snapshots), damit Reads praktikabel bleiben.
CQRS — Command Query Responsibility Segregation
CQRS trennt den Write-Path (Commands ändern Zustand und emittieren Events) vom Read-Path (Queries lesen aus vorberechneten Read-Modellen).
Command Side Query Side
(Write) (Read)
User Action User Query
│ │
▼ ▼
Command Handler Read Model / View
│ (denormalisierte Tabelle,
│ emits event optimiert für Query)
▼ ▲
Event Store (Kafka) │
│ │
└────────── Projector ──────────┘
(baut und updated
Read-Modelle aus Events)
Für Data-Plattformen mappt CQRS direkt auf die Medallion Architecture:
- Bronze Layer = Raw Event Log (Event Store)
- Silver Layer = bereinigte, gejointe Projektionen (Read Models)
- Gold Layer = business-ready Aggregationen (denormalisierte Views)
Apache Kafka als Backbone
Kafka ist der häufigste Event-Broker für Data-Plattformen bei größeren Volumen. Die wichtigsten Eigenschaften:
| Eigenschaft | Was es für Daten-Teams bedeutet |
|---|---|
| Persistent Log | Consumer können von jedem Offset replayen — ermöglicht Backfill |
| Consumer Groups | Mehrere Teams konsumieren denselben Event unabhängig |
| Partitioning | Parallelismus nach Key (z. B. user_id) für geordnete Verarbeitung |
| Retention | Retention nach Zeit oder Größe — Tage bis unendlich |
| Schema Registry | Avro/Protobuf-Schemas auf Producern erzwingen |
| Exactly-once Semantics | Konfigurierbare Garantien für kritische Finanz-Pipelines |
Eine Event-Driven Data-Pipeline bauen
1. Event-Schema-Design
Designe Events mit Daten-Consumern im Kopf. Schlechte Event-Schemas sind die Hauptursache für Schmerz in Event-Driven-Systemen.
// Gut: selbsterklärend, versioniert, keine domain-spezifischen Abkürzungen
{
"event_type": "order.placed",
"event_id": "evt_01HXK3M7N8P2Q4R5T6V7W8X9Y0",
"schema_version": "2.1",
"occurred_at": "2026-04-03T09:15:00Z",
"producer": "order-service",
"payload": {
"order_id": "ord_abc123",
"customer_id": "cust_xyz789",
"items": [
{"sku": "WIDGET-42", "quantity": 2, "unit_price_cents": 1999}
],
"total_cents": 3998,
"currency": "EUR"
}
}
// Schlecht: abgekürzt, keine Version, keine Schema-Info
{
"t": "ord_plcd",
"oid": "abc123",
"cid": "xyz",
"amt": 39.98
}
2. Kafka Producer (Python)
# Python — Kafka Producer mit Avro-Schema
from confluent_kafka import Producer
from confluent_kafka.schema_registry import SchemaRegistryClient
from confluent_kafka.schema_registry.avro import AvroSerializer
from confluent_kafka.serialization import SerializationContext, MessageField
import json
from datetime import datetime, timezone
KAFKA_BOOTSTRAP = "kafka:9092"
SCHEMA_REGISTRY_URL = "http://schema-registry:8081"
ORDER_PLACED_SCHEMA = '''
{
"type": "record",
"name": "OrderPlaced",
"namespace": "com.harbinger.orders",
"fields": [
{"name": "event_id", "type": "string"},
{"name": "order_id", "type": "string"},
{"name": "customer_id", "type": "string"},
{"name": "total_cents", "type": "long"},
{"name": "occurred_at", "type": "string"}
]
}
'''
schema_registry = SchemaRegistryClient({"url": SCHEMA_REGISTRY_URL})
avro_serializer = AvroSerializer(schema_registry, ORDER_PLACED_SCHEMA)
producer = Producer({"bootstrap.servers": KAFKA_BOOTSTRAP})
def publish_order_placed(order_id: str, customer_id: str, total_cents: int):
event = {
"event_id": f"evt_{order_id}_{int(datetime.now().timestamp())}",
"order_id": order_id,
"customer_id": customer_id,
"total_cents": total_cents,
"occurred_at": datetime.now(timezone.utc).isoformat(),
}
producer.produce(
topic="orders.placed",
key=customer_id, # partition by customer for ordering
value=avro_serializer(event, SerializationContext("orders.placed", MessageField.VALUE)),
)
producer.flush()
3. Stream Processing mit Flink / Spark Structured Streaming
# PySpark Structured Streaming — konsumiert Kafka, schreibt in Delta Lake
from pyspark.sql import SparkSession
from pyspark.sql.functions import from_json, col, to_timestamp
from pyspark.sql.types import StructType, StructField, StringType, LongType
spark = SparkSession.builder .appName("OrderEventsConsumer") .config("spark.sql.extensions", "io.delta.sql.DeltaSparkSessionExtension") .getOrCreate()
event_schema = StructType([
StructField("event_id", StringType()),
StructField("order_id", StringType()),
StructField("customer_id", StringType()),
StructField("total_cents", LongType()),
StructField("occurred_at", StringType()),
])
raw_stream = spark.readStream .format("kafka") .option("kafka.bootstrap.servers", "kafka:9092") .option("subscribe", "orders.placed") .option("startingOffsets", "latest") .load()
parsed = raw_stream .select(from_json(col("value").cast("string"), event_schema).alias("data")) .select("data.*") .withColumn("occurred_at", to_timestamp("occurred_at"))
query = parsed.writeStream .format("delta") .outputMode("append") .option("checkpointLocation", "s3://checkpoints/orders-placed/") .start("s3://lakehouse/silver/orders_placed/")
query.awaitTermination()
Event-Driven Patterns für Data-Plattformen
Outbox Pattern
Das Outbox Pattern löst ein häufiges Reliability-Problem: du schreibst in deine Datenbank und willst ein Event atomar in Kafka publizieren. Wenn du beides unabhängig schreibst, kann das eine gelingen während das andere fehlschlägt.
Lösung: Schreibe das Event in eine outbox-Tabelle in derselben
Datenbank-Transaktion wie dein Business-Write. Ein separater Prozess
(Debezium + Change Data Capture)
liest die Outbox und publiziert nach Kafka.
Event-Driven Feature Store
ML-Features aus Streaming-Events:
UserSignedUp-Event → Kafka → Flink aggregiert 7-Tage-Session-Counts → Redis Feature Store- Model Inference liest aus Redis (low-latency, frische Features)
- Dieselben Events landen in Delta Lake für Batch-Training
Dieses Pattern vermeidet Training/Serving-Skew — beide Pfade lesen aus derselben Event-Quelle.
Saga Pattern für verteilte Transaktionen
Wenn eine Operation mehrere Services umspannt (Order anlegen → Inventar reservieren → Payment durchführen), koordiniert ein Saga über Events statt einer verteilten Transaktion:
- Jeder Service publiziert ein Success- oder Failure-Event
- Compensating Events rollen vorherige Schritte bei Fehlern zurück
- Die Data-Plattform beobachtet alle Saga-Events für einen kompletten Audit-Trail
Trade-offs ehrlich gesagt
Event-Driven ist nicht universell besser. Die operative Komplexität ist real.
| Aspekt | Event-Driven | Batch |
|---|---|---|
| Latenz | Sekunden | Minuten bis Stunden |
| Komplexität | Hoch | Niedrig |
| Debugging | Schwer (verteilt) | Einfacher (Logs) |
| Ordering-Garantien | Nur pro Partition | Natürlich |
| Exactly-once | Konfigurierbar, schwer | Einfacher |
| Schema-Änderungen | Erfordert Koordination | Spaltenzugabe einfach |
| Team-Skill nötig | Kafka-Expertise | SQL/Python |
| Kosten | Kafka-Cluster-Overhead | Compute nach Zeitplan |
Fang mit Batch an, wenn dein Team klein ist und dein Business kein real-time braucht. Event-Driven-Komplexität für einen Batch-Use-Case ist Over-Engineering.
Wann Event-Driven für Daten einsetzen
Starke Signale:
- Du brauchst Sub-Minuten-Freshness in Dashboards oder operativen Systemen
- Mehrere Systeme brauchen dieselben Events unabhängig (keine enge Kopplung)
- Du baust ML-Features, die frische Verhaltenssignale brauchen
- Audit-Trail und Replay-Fähigkeit sind Requirements
Schwache Signale (lieber Batch):
- Daily Reporting reicht aus
- Einzelner Downstream-Consumer
- Team hat keine Kafka-Erfahrung
- Datenvolumen ist klein genug, dass Scheduled Queries funktionieren
FAQ
Brauche ich Kafka für Event-Driven? Nicht zwingend. Für kleinere Setups reichen NATS, Redis Streams oder cloud-native Optionen wie Google Pub/Sub. Kafka ist Standard bei größeren Volumen und mehreren Consumer-Gruppen.
Was ist der Unterschied zwischen Event Sourcing und Event-Driven? Event-Driven ist eine generelle Architektur-Pattern (Services kommunizieren über Events). Event Sourcing ist spezifischer: der Zustand der Anwendung wird ausschließlich aus dem Event-Log abgeleitet.
Wie skaliert Exactly-once in der Praxis? Exactly-once Kafka + idempotente Sinks (Delta Lake, Iceberg) funktionieren robust. Kosten: höhere Latenz und mehr Koordinations-Overhead. Reserviere es für Financial-Transaktionen und Audit-Trails.
Lohnt sich Event-Driven für deutsche Mittelständler? Wenn du < 5 Datenquellen, Tagesreporting und ein kleines Team hast: nein. Wenn du Multi-Channel-Commerce, Echtzeit-Inventory oder ML-Features brauchst: ja. Datenschutz/DSGVO ist bei Event-Logs ein eigenes Kapitel — Personenbezug muss explizit behandelt werden.
Fazit
Event-Driven Data Architecture ist kraftvoll, wenn Freshness wichtig ist und mehrere Consumer denselben Datenstrom brauchen. Event Sourcing gibt dir komplette, replayable History. CQRS trennt Write- von Read-Optimierung. Kafka liefert das dauerhafte, skalierbare Backbone.
Das Pattern hat reale Kosten: Kafka-Cluster, Schema-Management, Exactly-once-Semantik und verteiltes Debugging. Setze es ein, wo das Business genuin real-time braucht — nicht weil es modern klingt.
Nächster Schritt: Identifiziere eine Batch-Pipeline, bei der die 24-Stunden-Verzögerung ein konkretes Business-Problem verursacht. Das ist dein erster Kandidat für eine Event-Driven-Migration.
Weiterlesen
Stand: 14. Mai 2026.
Geschrieben von
Harbinger Team
Cloud-, Data- und AI-Engineer in DACH. Schreibt seit 2018 über infrastrukturkritische Tech-Entscheidungen — keine Marketing- Folien, sondern echte Trade-offs aus Production-Workloads.
Hat dir das geholfen?
Jede Woche ein neuer Artikel über DACH-Cloud, Data und AI — direkt in dein Postfach. Kein Spam, kein Marketing-Sprech.
Kein Spam. 1-Klick-Abmeldung. Datenschutz bei Loops.so.