Zum Hauptinhalt springen

Case Study: Technische Sanierung eines kritischen File-Exchange-Systems ohne Big-Bang-Migration

Maschinenbau-Konzern – Architektur-Refactoring ohne Big-Bang-Migration

Diese Case Study beschreibt die technische Sanierung eines geschäftskritischen File-Exchange-Systems mit Fokus auf Datenkonsistenz, kontrollierte Migration und minimale Downtime.


Executive Summary​

Ein konzernweites File-Exchange-Portal wies strukturelle Schwächen in Datenbankdesign, Dateiverwaltung und Konsistenzmechanismen auf.
Ziel war die technische Sanierung eines produktiven Systems ohne risikoreiche Komplettabschaltung.

Durch ein strukturiertes Architektur-Refactoring wurden:

  • Inkonsistente Datenstrukturen bereinigt
  • Orphan-Dateien und verwaiste Metadaten eliminiert
  • Atomare Synchronisation zwischen Datenbank und Dateisystem eingeführt
  • Eine deduplizierende Speicherstrategie implementiert
  • Eine SQL-basierte, persistente Job-Queue für parallele Hintergrundverarbeitung aufgebaut
  • Die Auditierbarkeit und Zugriffskontrolle verbessert
  • Eine kontrollierte Migrationsstrategie mit Rollback-Möglichkeit umgesetzt

Der operative Betrieb blieb stabil, die Downtime wurde auf ein minimales Wartungsfenster reduziert.


Ausgangssituation​

Das interne Web-Portal diente dem Austausch großer Dateien zwischen Fachabteilungen und externen Partnern – funktional vergleichbar mit OneDrive oder Dropbox.

Über Jahre gewachsen, zeigte das System folgende strukturelle Probleme:

  • Inkonsistente Spaltenbezeichnungen
  • Redundante Foreign Keys
  • Teilweise fehlende referenzielle Integrität
  • Mehrfach gespeicherte identische Dateien
  • Keine garantierte Atomarität zwischen Dateiupload und Metadatenpersistierung
  • Orphan-Dateien im Dateisystem
  • Verwaiste Metadatensätze in der Datenbank
  • Mangelnde Trennung zwischen Metadaten- und Speicherlogik

Ein direktes „In-Place-Refactoring“ war aufgrund des Produktivbetriebs nicht vertretbar.


Architektur-Ziele​

Die Sanierung folgte klar definierten Prinzipien:

  1. Kein Big-Bang-Ansatz
  2. Rollback-fähige Migration
  3. Atomare Konsistenz zwischen Datenbank und Filesystem
  4. Reduktion struktureller Risiken
  5. Entkopplung synchroner Prozesse durch asynchrone Hintergrundverarbeitung
  6. Vendor-unabhängige Storage-Architektur
  7. Deterministische, skalierbare Dateistruktur
  8. Verbesserte Auditierbarkeit

Architektur-Refactoring​

1. Parallele Tabellenstruktur statt In-Place-Änderung​

Die bestehende Tabellenstruktur wurde nicht modifiziert.
Stattdessen wurde eine neue, konsistente Struktur eingeführt:

  • Eindeutige Primary-Keys
  • Bereinigte Foreign-Key-Relationen
  • Vereinheitlichte Spaltenbenennung
  • Klare Trennung von Datei-Metadaten und Speicherreferenzen

Daten wurden kontrolliert in die neue Struktur kopiert.
Nach erfolgreicher Validierung wurde die alte Struktur entfernt.

Rollback war bis zur finalen Umschaltung möglich.


2. Virtuelles Dateisystem (Abstraktionslayer)​

Ein vollständig abstrahiertes virtuelles Dateisystem wurde implementiert.

Merkmale:

  • Keine direkte Verwendung von System.IO im Business-Code
  • Abstraktion von Dateien, Verzeichnissen und Streams
  • Austauschbarer Storage-Provider
  • Backend-unabhängige Hash-Berechnung (C#-basiert)
  • Übertragbar auf andere Systeme mit Datei-/Ordner-Struktur (z. B. S3)

Die Architektur reduziert Vendor-Lock-in und ermöglicht zukünftige Storage-Migrationen.


3. Git-ähnliche Speicherstruktur​

Zur Skalierung großer Dateimengen wurde eine deterministische Struktur eingeführt:

  • Dateien werden GUID-basiert gespeichert
  • Verzeichnisname = erste 2 Zeichen der GUID
  • Dateiname = restliche Zeichen
  • Flache, gleichmäßig verteilte Ordnerstruktur
  • O(1)-Lookup

Diese Struktur verhindert Verzeichnisüberlastung und bleibt unabhängig von der Gesamtanzahl gespeicherter Dateien performant.


4. Atomare Synchronisation zwischen DB und Filesystem​

Die Upload-Logik wurde transaktionssicher umgesetzt:

  1. Datei wird mit Temp-Präfix _ gespeichert
  2. Datenbank-Transaktion wird durchgeführt
  3. Bei Erfolg: atomisches Rename innerhalb derselben Partition
  4. Bei Fehler: Temp-Datei wird entfernt

Rename erfolgte als reine Umbenennung (kein Kopieren), somit atomar.

Ergebnis: Keine Inkonsistenzen zwischen Dateisystem und Datenbank.


5. Deduplizierung über asynchron berechnete Hashes​

Upload-Performance wurde nicht beeinträchtigt.
Hash-Berechnung erfolgt asynchron.

Ablauf:

  • Datei wird GUID-basiert gespeichert
  • Hintergrundjob berechnet Hash (IO-limitiert, konfigurierbarer Parallelismus)
  • Identische Hashes werden erkannt
  • Duplikate werden entfernt
  • Datenbank-Referenzen werden atomar umgeschrieben

Deduplizierung basiert auf:

  • Write-Once-Store
  • Späterem Linking
  • Idempotenter Verarbeitung

Konsistenz wurde logisch im Job sichergestellt (Index auf Hash vorhanden).


SQL-basierte asynchrone Job-Queue​

Zur Entkopplung kritischer Prozesse wurde eine persistente Job-Queue auf Basis der vorhandenen SQL-Datenbank implementiert.

Eigenschaften​

  • Statusmodell: Pending / Processing / Done / Failed / Error
  • Retry-Mechanismus mit Maximalversuchen
  • Fehlerprotokollierung inkl. Error-Message
  • Chunk-Verarbeitung (z. B. 200 Datensätze pro Job)
  • Idempotente Einzelverarbeitung
  • Alphabetisch nach ID sortierte Verarbeitung
  • Konfigurierbarer Parallelismus
  • IO-optimierte Hash-Verarbeitung
  • Transparente Auswertbarkeit über SQL

Nach Erreichen der maximalen Retry-Grenze wurde der Datensatz nicht weiterverarbeitet und protokolliert.

hinweis

Die Architektur verzichtete bewusst auf zusätzliche Infrastruktur (kein Kafka, kein externer Message-Bus), um Betriebsaufwand und Komplexität gering zu halten.


Konsistenz- und Orphan-Checks​

Regelmäßige Hintergrundprüfungen (täglich oder on demand):

  • Prüfung von Metadaten-Konsistenz
  • Prüfung physischer Datei-Hashes (nur falls noch nicht berechnet)
  • Erkennung von Orphan-Dateien
  • Erkennung verwaister Metadatensätze

Bereinigung war konfigurierbar:

  • Nur Logging
  • Logging + automatische Löschung

Die Anzahl fehlerhafter Jobs war über die Datenbank transparent auswertbar.


Migrationsstrategie​

Die Migration erfolgte kontrolliert:

  1. Einführung der neuen Tabellenstruktur
  2. Referenzierung bestehender Dateien
  3. Testphase im Produktivsystem
  4. Manuelle Aktivierung des Post-Migration-Jobs
  5. Physische Übertragung alter Dateien
  6. Finaler Cutover

Rollback war bis zur Aktivierung des Post-Migration-Jobs möglich.

Shutdown-Zeit wurde auf ein minimales Wartungsfenster reduziert, da große Datenmengen asynchron im Hintergrund übertragen wurden.


Verbesserte Zugriffskontrolle & Auditierbarkeit​

Durch das Refactoring wurden:

  • Eindeutige Datei-Mandanten-Beziehungen hergestellt
  • Verwaiste Berechtigungsreferenzen entfernt
  • Konsistente Audit-Referenzen ermöglicht
  • Löschvorgänge nachvollziehbar gemacht

Das System wurde revisionssicherer und strukturell robuster.


Technisches Ergebnis​

Die Sanierung führte zu:

  • Eliminierung struktureller Inkonsistenzen
  • Verlässlicher atomarer Datei-/DB-Synchronisation
  • Deduplizierung identischer Dateien
  • Bereinigung historischer Altlasten
  • Reduktion operativer Risiken
  • Verbesserter Wartbarkeit
  • Kontrollierter, rollback-fähiger Migration
  • Entkopplung kritischer Prozesse durch persistente Hintergrundverarbeitung
  • Storage-agnostischer Architektur

Architektur-Leitprinzipien​

  • Minimierung von Komplexität
  • Keine zusätzliche Infrastruktur ohne Notwendigkeit
  • Idempotente Verarbeitung
  • Persistente, wiederholbare Jobs
  • Deterministische Dateistruktur
  • Saubere Trennung von Metadaten und Storage
  • Risikominimierte Migration statt Big-Bang

Fazit​

Die technische Sanierung eines produktiven File-Exchange-Systems wurde ohne disruptive Komplettmigration umgesetzt.

Durch eine Kombination aus:

  • strukturellem Datenbank-Refactoring
  • atomarer Datei-/DB-Kopplung
  • SQL-basierter persistenter Job-Queue
  • asynchroner Deduplizierung
  • deterministischer Speicherstruktur
  • kontrollierter Migrationsstrategie

konnte ein historisch gewachsenes, risikobehaftetes System in eine robuste, wartbare und skalierbare Architektur überführt werden.

Der Fokus lag nicht auf Feature-Erweiterung, sondern auf der nachhaltigen Stabilisierung eines geschäftskritischen Systems.