Neu

msg digital mehr

Gradient gelb

Brauchen Sie dringend realistische Testdaten?

Wie wir mit Databricks in 2 Stunden auf 900 GB skaliert haben

Datengenerierung einfach und reproduzierbar machen

Im Zeitalter der Cloud-Daten bleibt der Zugriff auf produktionsähnliche Datensätze zu Testzwecken eine große Herausforderung, die oft durch strenge Sicherheits- und Datenschutzbedenken eingeschränkt wird. Zuverlässige künstliche Datensätze sind entscheidend für die Bewertung der Leistung und Performance von Cloud-Datenplattformen unter realen Bedingungen. Bei msg verwenden wir Spark on Databricks, um qualitativ hochwertige, synthetische Datensätze zu generieren und datengesteuerte Entscheidungen zu ermöglichen, die kundenspezifische Anforderungen effektiv erfüllen.

Unser Ziel war es, einen wiederholbaren Datengenerierungsprozess zu entwickeln, der es den Benutzern ermöglicht, identische Ergebnisse mit derselben Konfiguration zu erzielen und so konsistente Tests zu gewährleisten. Als Grundlage dieses Prozesses dient ein klar definiertes Datenmodell, das die erforderlichen Tabellen und ihre Verbindungen skizziert, um Konsistenz und referenzielle Integrität zu wahren. Mit Databricks richten wir effizient eine Spark-Umgebung mit minimalen Konfigurationen ein, die die Zuverlässigkeit und Wiederholbarkeit bietet, die für eine robuste Datengenerierung unerlässlich sind.

 

Aktuelle Herausforderungen der Datengenerierung

Moderne Big-Data-Tools sind für die Verarbeitung riesiger Datenmengen ausgelegt und spiegeln die wachsende Größe von Produktionsdatensystemen wider.  Um aussagekräftige Auswertungen für reale Produktionssysteme zu ermöglichen, müssen künstliche Datensätze produktionsähnliche Daten genau nachbilden.  Dadurch wird sichergestellt, dass Benchmarking-Technologien und Verarbeitungs-Engines Erkenntnisse liefern, die direkt auf reale Szenarien anwendbar sind. Das Erreichen von referenzieller Integrität ist in Big-Data-Umgebungen aufgrund der Abhängigkeiten zwischen Tabellen eine besondere Herausforderung. Diese Abhängigkeiten verhindern eine vollständige Verteilung von Arbeitslasten, was im großen Stil noch problematischer wird, da nicht alle Prozesse parallel ausgeführt werden können.  Um die Kompatibilität und Komprimierung gründlich zu bewerten, müssen Datensätze in mehreren Formaten und mit unterschiedlichen Datentypen generiert werden, um sicherzustellen, dass sie realen Szenarien ähneln. Zusätzlich liefert das Testen der Leistung über Formate hinweg Einblicke in die Effizienz von Verarbeitungs-Engines unter verschiedenen Bedingungen.

 

Warum Databricks?

Databricks mit seinem Managed-Spark-Service bot eine ideale Plattform für die künstliche Datengenerierung, aufgrund der folgenden Vorteile:

  • Managed Service (Verwalteter Dienst): Databricks vereinfacht die Einrichtung und Verwaltung von Spark und ermöglicht es uns, die Umgebung schnell und ohne administrativen Aufwand bereitzustellen und zu konfigurieren
  • Low-Level Coding Capabilities (Low-Level-Codierungsfunktionen): Spark ermöglicht den direkten Zugriff auf Low-Level-APIs wie RDDs, was eine präzise Steuerung über Datenverarbeitungs-Workflows ermöglicht und es für komplexe Aufgaben der Datengenerierung  geeignet macht.
  • Horizontal Scalability (Horizontale Skalierbarkeit): Die verteilte Rechenfähigkeit von Spark, kombiniert mit der dynamischen Cluster-Verwaltung von Databricks, ermöglichte es uns, horizontal zu skalieren und große Datensätze effizient zu verarbeiten.
  • Efficient Custom Code (Effizienter benutzerdefinierter Code): Mit Scala, einer JVM-basierten Sprache, haben wir leistungsfähige UDFs implementiert, die die Effizienz und Flexibilität des Datengenerierungsprozesses verbessern.
  • Cloud Agnostic (Cloud-agnostisch): Databricks lässt sich nahtlos in alle großen Cloud-Anbieter integrieren, um Flexibilität zu gewährleisten und eine Anbieterbindung zu vermeiden.
  • Cost Efficiency (Kosteneffizienz): Die verbrauchsabhängige Preisgestaltung von Databricks stellte sicher, dass wir nur für die Ressourcen bezahlten, die während der Datengenerierung verwendet wurden, während Job-Cluster die Kosten optimierten, indem sie Ressourcen bei Bedarf skalierten.

Durch die Nutzung von Databricks und Spark haben wir eine robuste, skalierbare und kosteneffiziente Lösung errichtet, die die hohen Anforderungen der künstlichen Datengenerierung für Benchmarking und Tests erfüllt.

 

Beispiel für ein Zieldatenmodell

Die folgende Grafik veranschaulicht das Datenmodell und zeigt die Beziehungen zwischen den Schlüsseltabellen, wie z. B. Länder, Kunden, Anbieter, Bestellungen, Dienstleistungen und mehr.

Data model diagram showing tables for Customers, Orders, Providers, Services, and related dimensions with keys and relationships for synthetic data generation.

Datenmodell, das für die Generierung synthetischer Daten verwendet wird

 

Obwohl das spezifische Datenmodell nicht entscheidend ist, da jedes Modell mit mehreren Beziehungen diesen Zweck erfüllen könnte, haben wir dieses Beispiel gewählt, weil es verschiedene Datentypen, einschließlich UUIDs, enthält und Klarheit für das Verständnis des verwendeten Codes und Vorgehensweise bietet.

 

Datengenerierung mithilfe von Spark’s RDDs

Die Abstraktion von Resilient Distributed Datasets (RDDs) (widerstandsfähige verteilte Datensätze) durch Spark ermöglicht eine effiziente verteilte Datenverarbeitung über mehrere Knoten hinweg, eine Fähigkeit, die wir eingesetzt haben, um einen leistungsstarken Datengenerierungsprozess zu entwickeln.  Um die Reproduzierbarkeit und den Determinismus in unserem Datensatz zu gewährleisten, haben wir eine Instanz der Random-Klasse mit einem vordefinierten Seed initialisiert. Dieser Seeded-Zufallsgenerator wurde verwendet, um ein RDD mit Seed-Werten zu erstellen, der die Parallelität während der Datengenerierung erhöhte und gleichzeitig die Einzigartigkeit des resultierenden Datensatzes beibehält:

Scala code snippet using a fixed seed (1876) to generate a parallelized RDD of random long values for reproducible synthetic data generation in Spark.

 

Um Tabellenzeilen eindeutig zu identifizieren, haben wir UUIDs eingeführt, die in realen Systemen weit verbreitet sind.  Dieser Ansatz garantiert zwar eindeutige Datensätze, stellt jedoch die Herausforderung dar, konsistente Beziehungen zwischen Tabellen aufrechtzuerhalten. Ohne eine solche Konsistenz würden Fremdschlüsselreferenzen nicht übereinstimmen, was die Nützlichkeit des Datensatzes für Benchmarking-Zwecke untergraben würde.

Um dies zu adressieren, haben wir während des Datengenerierungsprozesses eine temporäre Indexspalte integriert.  Dieser Index stellt sicher, dass UUIDs für Fremdschlüssel nicht unabhängig generiert, sondern vom Index der referenzierenden Tabelle abgeleitet werden. Auf diese Weise haben wir die relationale Integrität des gesamten Datensatzes bewahrt und robuste Benchmarking-Fähigkeiten ermöglicht.

Um die Integrität des gesamten Datensatzes zu wahren und ein robustes Benchmarking zu ermöglichen, haben wir zunächst Tabellen ohne Verweise generiert und Beziehungen hergestellt, indem wir in den nachfolgenden Schritten Fremdschlüssel verknüpft haben. Um den Datengenerierungsprozess zu veranschaulichen, verwenden wir die Tabellen „Kunden“ und „Bestellungen“ als Beispiel. Wir begannen mit der Definition einer Klasse zur Strukturierung der Kundenrohdaten, wobei Langwerte für ihre Effizienz bei der Generierung von Zufallsverteilungen verwendet wurden, wobei die tatsächlichen Werte im nächsten Schritt erstellt wurden:

Scala case class CustomerRaw defining a customer schema with fields such as customer ID, name, email, birth date, address index, registration date, and active status, mostly using Long data type.

 

Mithilfe von seedRDD haben wir Chargen von pseudozufälligen Seed-Werten erstellt, die auf ihre Größe abgestimmt waren. Dies ermöglicht die Reproduzierbarkeit von Datensätzen. Das bedeutet, dass das zweimalige Ausführen des Algorithmus die gleichen Datensätze mit denselben Werten liefert.

Databricks - Blog 4

 

Diese Zahlen wurden dann in einen Spark-DataFrame umgewandelt und durch Hilfsfunktionen verarbeitet, um synthetische, aber aussagekräftige Werte zu erstellen, z. B. gültige E-Mails (mit „@“-Symbolen), formatierte Geburtsdaten und UUIDs. Nachschlagetabellen, z. B. solche mit Namen und Adressen, erhöhten die Kontextrelevanz der Daten weiter.

Dieser Ansatz gewährleistet einen deterministischen und skalierbaren Datengenerierungsprozess, der es uns ermöglicht, sowohl die Einzigartigkeit als auch die Reproduzierbarkeit in künstlichen Datensätzen aufrechtzuerhalten.

 

Verwaltung der Beziehung zwischen Tabellen

Der Erstellungsprozess für die Tabelle „Bestellungen“ folgt einem ähnlichen Ansatz wie für die Tabelle „Kunden“, wobei seedRDD verwendet wird, um zufällige Daten in Chargen zu generieren und gleichzeitig Konsistenz und Reproduzierbarkeit zu gewährleisten. Es wurde jedoch ein zusätzlicher Schritt eingebunden, um die referenzielle Integrität zwischen den Tabellen „Bestellungen“ und „Kunden“ sicherzustellen. Während der Datengenerierung wurde der customerIndex als temporäres Feld eingeschlossen, sodass die „Bestellungen“-Tabelle genau auf den entsprechenden Kundendatensatz verweisen konnte. Durch das Verknüpfen der Tabelle „Bestellungen“ mit der Tabelle „Kunden“ in diesem Index haben wir die UUID jedes Kunden abgerufen, um die Fremdschlüsselspalte in der Tabelle "Bestellungen" aufzufüllen. Diese Methode stellte sicher, dass alle Beziehungen korrekt hergestellt wurden und den Anforderungen an die relationale Integrität des Datenmodells entsprachen. Durch Auslassung des expliziten Codes der Kürze halber unterstreicht dieser optimierte Prozess, wie wichtig es ist, miteinander verbundene Datensätze für ein robustes Benchmarking und Testen zu entwerfen.

Nach der Generierung des Datensatzes waren wir in der Lage, die Tabellen in verschiedenen  Dateiformaten zu schreiben – CSV, JSON (komprimiert mit gzip) und Parquet (komprimiert mit Snappy), um den Speicher für verschiedene Anwendungsfälle zu optimieren. Dieser Ansatz:

  • Emuliert eine reale Datenplattform, die Daten in verschiedenen Formaten speichert
  • Ermöglicht das Testen und Benchmarking mit unterschiedlichen Compute Engines und analytischen Workflows
  • Hält die Speicherkosten niedrig, indem Dateien komprimiert werden, was für große Datenmengen von Vorteil ist.
  • Ermöglicht es uns, fast 89 GB Daten (komprimiert) in etwa 27 Minuten zu erstellen (Azure Compute: Standard_D8s_v3, Westeuropa, 6 Arbeiter, 10,5 DBU, Kosten: 0,93 $)
  • Ermöglicht es uns, mehr als 900 GB Daten (komprimiert) in etwa 2 Stunden zu erstellen (Azure Compute: Standard_D8s_v3, Westeuropa, 6 Arbeiter, 10,5 DBU, Kosten: 0,93 $)

 

Was haben wir erreicht?

Wir haben gezeigt, wie Databricks mit seiner verwalteten Spark-Umgebung eine ideale Plattform für die Generierung künstlicher Datensätze bietet, die auf reales Benchmarking zugeschnitten sind.  Durch die Erstellung synthetischer Daten mit realistischen Verteilungen und referentieller Integrität haben wir die Fähigkeit erlangt, reale Bedingungen zu simulieren und Verarbeitungsmaschinen und -technologien gründlich zu bewerten. Die Skalierbarkeit und Flexibilität von Databricks optimierte den Prozess und ermöglichte es uns, effizient große, qualitativ hochwertige Datensätze zu erstellen. Diese Fähigkeiten verbesserten nicht nur unsere Test-Workflows, sondern ermöglichten es uns auch, datengestützte Entscheidungen mit Zuversicht zu treffen und so die Ausrichtung an die Anforderungen der realen Welt sicherzustellen.

Haben Sie Fragen? Sprechen Sie uns an!

Schamberger, Tom edited

Tom Schamberger

Head of Cloud Data Platforms