Tristan Nolde 98a189b94c
docs: Abschlussarbeit on data ingestion (#500)
Co-authored-by: Philipp Horstenkamp <philipp@horstenkamp.de>
2024-01-02 15:50:58 +01:00

6.9 KiB
Raw Blame History

4.2 Lösungsarchitektur

Im Verlauf der Entwicklung stellte sich heraus, dass eine zentrale Stelle zur Datenspeicherung benötigt wird, damit Entwickler Zugang zu den Daten sowohl im Staging-Bereich als auch in der Produktiv-Form haben. Die bereits in der ersten Phase des Projektes angelegte MongoDB im Atlas Hosting (internet-facing) wurde daher durch eine auf der FH-Infrastruktur gehostete Konstruktion ersetzt, die aus einer MongoDB und einer PostgreSQL-Datenbank besteht:

Überblick über die Netzwerkarchitektur des FH K8s Clusters

Da es sich bei dem zur Verfügung gestellten System um einen Kubernetes (K8s) Host handelt, wurden entsprechende Manifeste angelegt und auf dem Server bereitgestellt.

Aufgrund der in der FH eingesetzten Netzwerkarchitektur war es jedoch nur möglich, den Server von außen über eine VPN-Verbindung (ForcePoint) zu erreichen. Dies stellte zwar keine große Herausforderung für die Projektteilnehmer dar, blockierte jedoch die Anbindung des selbst gehosteten Apache Airflow Servers. Daher wurden die regelmäßig bezogenen News-Artikel weiterhin in die im Internet stehende MongoDB gespeist und etwa einmal im Monat manuell in die FH-Infrastruktur überführt.

Nach dem Aufsetzen des Development Environments und den ersten Entwicklungsfortschritten galt es, eine Zielarchitektur zu bestimmen. Aufgrund der Vorteile in Portabilität und Unabhängigkeit von den Gegebenheiten verschiedener Clients wurde sich für eine Docker-basierte Lösung entschieden. Die einzelnen Docker Container, respektive Images, wurden anhand ihrer Anwendungsdomäne sowie des geplanten Datenflusses geschnitten:

Die Aufgaben der Container wurden wie folgt verteilt:

  1. Data Ingestion:

    • Beziehen von Unternehmensdaten sowie News-Artikeln
    • Aufbereitung dieser Daten
    • Überführung in die Staging DB zur weiteren Verarbeitung
  2. Staging DB:

    • Persistierung der "Roh-Daten"
    • Fachliche Trennung von Darstellung und Analyse
  3. Data Loader:

    • Transformation der "Roh-Daten" in das für die Visualisierung benötigte Ziel-Format
    • Durchführung weiterer Analyse-Bausteine (unter anderem Sentiment)
    • Überführung in die ProdDB
  4. ProdDB:

    • Persistierung der Daten im Schema für die Visualisierung
  5. Dashboard Server:

    • Webserver zur Bereitstellung der UI
    • Dazugehörige Geschäftslogik (z.B. Aufbereitung der Graphen)

Diese Aufteilung entstand unter anderem nach der Identifikation der verschiedenen Aufgaben-Domänen sowie ihrer Features:

Im Detail:

Auch für dieses Konstrukt galt es, eine Ausführungsumgebung zu bestimmen. Da sich der Umgang mit K8s für die Gruppe aufgrund mangelnder Erfahrung als nicht durchführbar erwies, wurde stattdessen auf den hinter jupiter.fh-swf liegenden Server zurückgegriffen. Bei diesem handelt es sich um einen Docker Swarm Host, auf dem bereits unterstützende Tools wie NGINX oder Portainer installiert sind.

Für das Deployment selbst wurde zunächst neben dem automatisierten Bau der verwendeten Docker Images eine docker-compose.yml entwickelt. Diese Datei erfasst alle benötigten Komponenten, verknüpft sie über entsprechende Konfigurationen des Docker-Netzwerks und Umgebungsvariablen miteinander und steuert schließlich die Verteilung auf dem Swarm Cluster. Um eine automatisierte Bereitstellung der Services sowie Aktualisierung dieser zu ermöglichen, wurde mit Portainer ein neues Deployment namens transparenzregister erstellt und mit dem Code-Repository verknüpft. Auf diese Weise überprüft Portainer in regelmäßigen Intervallen, ob relevante Änderungen im Repository vorliegen sei es eine direkte Modifikation an der docker-compose.yml oder die Bereitstellung eines neueren Docker Images. Bei einer solchen Erkennung startet Portainer automatisch das Deployment erneut. Zudem wurde die NGINX-Konfiguration des Jupiter Servers erweitert, und der Webserver des Transparenzregisters so unter https://jupiter.fh-swf.de/transparenzregister dem Internet zur Verfügung gestellt. Die damit verbundenen Anpassungen an der Konfiguration des Deployments, wie etwa die Einführung des BASE_PATHs /transparenzregister und die Integration von Basic Auth, um den Service vor Zugriff Externer zu schützen, wurden ebenfalls über die docker-compose.yml ermöglicht.

Auch wenn das Deployment anfangs wie gewünscht ablief, traten im Laufe der Zeit einige Probleme auf. Die hohe Frequenz an Änderungen am main-Branch, der vom automatisierten Deployment überwacht wird, durch die Integration von Dependabot sorgte dafür, dass schnell aufeinander folgende Deployments auf dem Server gestartet wurden und somit eine hohe Downtime der Services entstand. Ebenfalls hatte dies den Seiteneffekt, dass Unmengen an Docker Images erstellt und auf den Server transportiert wurden. Dies hatte in Kombination mit der ohnehin hohen Anzahl an teilweise veralteten Images zur Folge, dass der Speicherplatz auf dem Server an seine Grenzen geriet. Dieser Herausforderung hätte durch eine feinere Steuerung des Deployments begegnet werden können. Unter anderem hätten Änderungen erst auf einem develop- oder release-Branch gesammelt und erst bei Vollendung mehrerer Features oder relevanter Änderungen (z.B. Aktualisierung eingesetzter Bibliotheken) auf den main-Branch überführt und somit in das Deployment übergeben werden können. Eine erweiterte Versionierungsstrategie der Images (z.B. nach Semantic Versioning) hätte ebenfalls unterstützen können. Alternativ hätten Vorkehrungen getroffen werden müssen, um die auf dem Jupiter Server abgelegten Docker Images regelmäßig aufzuräumen.

Für die lokale Entwicklung sowie das Testen wurde zusätzlich eine local-docker-compose.yml angelegt. Diese Datei beinhaltet den grundlegenden Aufbau des Produktiv-Deployments, wurde jedoch so angepasst, dass auf ein lokales Build der Docker Images aufgebaut wird. Zudem wurde ein zusätzlicher Container eingeführt, der die Staging DB zu Beginn mit einem Snapshot der eingesetzten Daten füllt, um somit den gesamten Datenfluss abspielen zu können. Näheres zum Aufsetzen wird in der README beschrieben. Um den kompletten Build Process neu zu starten, wurde zusätzlich die rebuild-and-start.bat angelegt, welche die dort beschriebenen Schritte in einem Skript kapselt.