Zurück zur Startseite

Streaming-Datenverarbeitung: Architektur mit Kafka und Flink

Artikel zum Aufbau eines Streaming-Datenverarbeitungssystems mit Apache Kafka, Flink und S3. Integrationsstufen, Konfigurationsbeispiele und Best Practices für die Produktionsumgebung werden detailliert behandelt.

Ein Streaming-System wie ein LEGO-Baukasten bauen: praktischer Leitfaden
Advertisement 728x90

# Streamverarbeitung: Architektur wie LEGO-Steine

Moderne Datenverarbeitungssysteme erfordern Flexibilität und Skalierbarkeit. In diesem Artikel zerlegen wir, wie man Kafka, Flink, S3 und andere Komponenten zu einer einheitlichen Streaming-Plattform mit modularen Architekturprinzipien kombiniert. Wir tauchen detailliert in die Integrationsstufen ein, von der Datengenerierung bis zur Echtzeit-Analyse.

Systemgrundlage: Streaming-Plattform

Um Streamverarbeitung aufzubauen, verwenden wir einen Stack aus erprobten Technologien. Die zentrale Komponente ist Apache Kafka – eine verteilte Streaming-Plattform, die zuverlässige Nachrichtenübermittlung gewährleistet. Daneben setzen wir ein:

  • Kafka Connect zur Integration mit externen Systemen
  • Schema Registry zur Verwaltung von Datenschemata
  • Kafka UI als visuelle Verwaltungsoberfläche

Die zentrale Idee ist, Komponenten wie LEGO-Steine zu behandeln. Jede übernimmt eine spezifische Funktion und verbindet sich mit anderen über klar definierte Schnittstellen. Um eine minimale Einrichtung zu starten, reichen Docker Compose und Git LFS. Das System wird über Multi-Stage-Builds zusammengesetzt, was reproduzierbare Umgebungen gewährleistet.

Google AdInline article slot

Beispielhafte Basis-Konfiguration in docker-compose.yml:

services:
  kafka:
    image: confluentinc/cp-kafka:8.1.0
    environment:
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092

  schema-registry:
    image: confluentinc/cp-schema-registry:8.1.0
    environment:
      SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: kafka:9092

Es ist wichtig, den Unterschied zwischen traditionellen Datenbanken und Streaming-Systemen zu verstehen. In relationalen DBMS liegt der Fokus auf Zustand (Tabellen, Datensätze), während in der Streamverarbeitung Events im Vordergrund stehen. Jede Nachricht in Kafka stellt ein unveränderliches Event dar, das ans Ende des Logs angehängt wird. Dieser Ansatz ermöglicht Systeme mit garantierter Zustellung und Zustandswiederherstellung.

Stufen der Datenintegration

Wir teilen den Prozess des Systemaufbaus in vier logische Stufen ein:

Google AdInline article slot
  • Ingest – Empfang von Daten aus externen Quellen
  • Storage – persistente Speicherung
  • Transform – Transformation und Anreicherung
  • Serve – Bereitstellung der Ergebnisse

Ingest: Datengenerierung und -aufnahme

In der Ingest-Stufe konfigurieren wir die Datenquelle über Kafka Connect. Zur Demonstration implementieren wir einen Generator für Temperaturmessungen von Sensoren. Der Java-Connector erzeugt synthetische Daten mit geografischen Koordinaten und Temperatur, unter Berücksichtigung der Tageszeit und der Position relativ zum Äquator.

Connector-Konfiguration:

{
  "connector.class": "dev.miron.connect.temp.TempSourceConnector",
  "tasks.max": "1",
  "topic": "earth-temp",
  "sensors": "5",
  "messages.per.sensor.per.second": "1"
}

Beachten Sie die Verwendung von Avro zur Serialisierung. Nachrichten werden im binären Format gespeichert, was den Datenverkehr reduziert und die Verarbeitung beschleunigt. Schema Registry kümmert sich um Schema-Versionierung und Kompatibilitätsprüfungen (BACKWARD-Modus). Bei Änderungen der Datenstruktur weist das System ungültige Updates automatisch zurück.

Google AdInline article slot

Storage: Langfristige Speicherung

Für persistente Speicherung nutzen wir eine Kombination aus S3 und Apache Iceberg. S3 dient als Objektspeicher, während Iceberg eine Metadatenschicht hinzufügt, die ACID-Transaktionen und Time Travel ermöglicht. Dieser Ansatz bewältigt große Datensätze effizient und vermeidet Probleme traditioneller Dateisysteme.

Sink-Connector-Konfiguration:

{
  "connector.class": "io.confluent.connect.s3.S3SinkConnector",
  "topics": "earth-temp",
  "s3.bucket.name": "data-lake",
  "storage.class": "io.confluent.connect.s3.storage.S3Storage",
  "format.class": "io.confluent.connect.s3.format.avro.AvroFormat"
}

Für Datenabfragen verwenden wir Trino – einen verteilten SQL-Engine, der Daten aus mehreren Quellen föderieren kann. Das ermöglicht komplexe analytische Abfragen ohne Datenverschiebung.

Daten-Transformation

Wir implementieren die Transform-Stufe mit Apache Flink – einem Stream-Processing-Engine, der Windows und stateful Operations unterstützt. Beispielaufgabe: Umwandlung der Temperatur von Fahrenheit nach Celsius und Filterung anomaler Werte.

DataStream<TempEvent> processed = source
  .map(event -> {
    event.setCelsius((event.getFahrenheit() - 32) * 5/9);
    return event;
  })
  .filter(event -> event.getCelsius() > -50 && event.getCelsius() < 60);

Flink integriert sich mit Kafka über native Connectoren. Es ist entscheidend, Checkpointing korrekt zu konfigurieren, um Exactly-Once-Verarbeitungs-Garantien zu gewährleistet. Wichtige Parameter:

  • execution.checkpointing.interval: 60000
  • state.backend: rocksdb
  • state.checkpoints.dir: file:///checkpoints

Zur Überwachung nutzen wir die integrierte Weboberfläche von Flink, um Verzögerungen (Lag) und Operator-Zustände zu verfolgen.

Service-Ebene

In der finalen Stufe stehen Daten Verbrauchern zur Verfügung. Wir implementieren zwei Optionen:

  • PostgreSQL über JDBC-Connector für operative Abfragen
  • Redis zum Cachen heißer Daten

PostgreSQL-Sink-Konfiguration:

{
  "connector.class": "io.confluent.connect.jdbc.JdbcSinkConnector",
  "connection.url": "jdbc:postgresql://postgres:5432/analytics",
  "topics": "processed-temp",
  "auto.create": "true",
  "insert.mode": "upsert",
  "pk.fields": "sensorId,timestamp"
}

Für Redis verwenden wir einen benutzerdefinierten Connector, der die neuesten Messwerte für jeden Sensor in Hash-Tabellen speichert. Das liefert Millisekunden-Latenz für Abfragen zu aktuellen Daten.

Wichtige Erkenntnisse

  • Datenschemata müssen über Schema Registry mit BACKWARD-Kompatibilität verwaltet werden
  • Stateful Processing in Flink erfordert Checkpointing-Einrichtung und Auswahl eines State-Backends
  • Systemzerlegung in Ingest/Storage/Transform/Serve-Stufen vereinfacht das Debugging
  • Binäre Serialisierung (Avro/Protobuf) ist entscheidend für die Leistung von Streaming-Systemen
  • Konfigurationstests über Docker Compose ermöglichen schnelle Iterationen

— Editorial Team

Advertisement 728x90

Weiterlesen