Was die Datenübertragung aus Legacy Systemen mit Spotify gemeinsam hat
Spotify fasst die letzten 10 Jahre für über 248 Millionen User in personalisierten Playlists zusammen.
Erstmals im Jahr 2016 hat Spotify einen persönlichen Rückblick für die User erstellt. Die Herausforderungen im Jahr 2019 waren ungleich größer, da sich die zu analysierende Musikstreams alleine im Vergleich zu 2018 verfünffacht hatten. Nichtsdestotrotz hat es Spotify auch Ende 2019 geschafft die gesamte Hörstatistik der letzten 10 Jahre für über 248 Millionen User zu analysieren. Daraus wurde für jeden Nutzer ein persönlicher Jahresrückblick mit personalisierten Playlists erstellt.
Technisch nutzt Spotify seit 2016 die Google Cloud und gilt dort als einer der größten Abnehmer von virtuellen Rechenressourcen. Alleine für die ersten drei Jahre nach dem Umzug zu GCP, hat Spotify über 450 Mio-$ für die Cloudkosten eingeplant, um die schier unendliche Datenmenge bewältigen zu können. Gemeinsam mit den Engineering Teams von Google entstand so zum wiederholten Male der größte Dataflow Analysejob, der jemals in der Google Cloud ausgeführt wurde. Bei diesen enormen Datenmengen sind solche Berechnungen natürlich auch eine finanzielle Belastung, sodass ein solcher Vorgang sehr gut geplant sein will und nicht einfach von vorne gestartet werden kann. Google berechnet in GCP je nach Tarif nach Stunden oder Datenmengen. Beides war in diesem Fall gigantisch.
Der angesprochen GCP Service „Dataflow“ basiert auf dem open-source Projekt Apache Beam. Apache Beam ist ein Framework bzw. ein Modell für die Definition und die Erstellung von Datenverarbeitungspipelines. Bereits vor dem Umzug in die Google Cloud hat Spotify begonnen ein Scala Framework namens „Scio“ zu entwickeln, dass die Apache Beam API in Scala abstrahiert. Apache Beam und somit auch Scio bieten alle notwendigen Werkzeuge, um gigantische ETL Transaktionen in Form von Batch- oder Streamingjobs abarbeiten zu können. Die in „Scio“ programmierten Jobs können dann Serverless direkt in Google Dataflow ausgeführt werden.
Scala, Scio und Dataflow als „Serverless Wunderwaffe“ für die Verarbeitung von Legacydaten.
Da auch der überwiegende Teil unserer Kundenprojekte und unserer Produkte in der Google Cloud laufen, ist Scio für uns ein ideales Werkzeug, um Legacydaten aus Altsystemen in die Cloud zu bringen. Dabei können die Jobs einmalig als Batch laufen oder auch danach kontinuierlich neue Daten in das neue System streamen, wenn das Altsystem übergangsweise parallel betrieben wird. Da Google die Infrastruktur managed und alles Serverless abläuft, ist dies für uns eine sehr kosteneffiziente Möglichkeit Altsysteme anzubinden. Gleichzeitig verwenden wir Scio Jobs auch für BigData Analysen die z.B. in ein BigQuery Data Warehouse geschrieben werden. Die Vorteile für uns als innFactory liegen auf der Hand:
- Problemlose Skalierung über alle Größen
- Geringer Entwicklungsaufwand
- Scala als unsere favorisierte Backendsprache
- Sehr stabile Jobs, die auch auf lokalen Systemen ausprobiert werden können.
Scio 101 – Datentransformation aus und zu Postgres
Das nachfolgende Beispiel soll einen ersten Einblick bieten, wie man Legacydaten aus einem Altsystem, bzw. aus deren Datenbank in eine neue Datenbank in der Cloud überführen kann. Das gesamte Beispiel ist auch im innFactory GitHub Account zu finden.
Das Beispiel zeigt, wie Benutzerdaten aus Postgres Datenbank 1 transformiert in eine neue Postgres Datenbank 2 geschrieben werden können.
Zu Beginn unseres Jobs sollen die Zugangsdaten aus den Kommandozeilenargumenten / Dataflowparametern für die Datenbanken extrahiert werden. Diese Argumente benötigen wir später für den Scio-Context zum Lesen und Schreiben der Daten via JDBC.
Scio bietet uns die Möglichkeit alle Daten konsistent aus der alten Datenbank zu streamen und die Zeilen auf unsere Case-Klassen zu mappen. Die Case-Klassen können wir dann im nächsten Schritt weiterverarbeiten und als Side-Output in die neue Datenbank schreiben. Da wir in Scio, ähnlich wie in Spark, mithilfe von „higher ordered functions“ einen „DAG“ (directed acyclic graph) definieren, kann Apache Beam die Ausführung des gesamten Flows vor dem Lauf optimieren. Darüber hinaus sorgt Dataflow dafür, dass sowohl die Quelle als auch das Ziel nicht mit zu vielen Daten überlastet wird. Unser Beispiel zählt am Ende somit noch die verarbeiteten Personen und gibt diese auf der Konsole aus.
Zum Starten des Beispiels kann nachfolgender Befehl verwendet werden:
Zusammenfassung
Da sich Apache Beam um die Threads und die Verteilung unseres Jobs kümmert, können wir uns auf die wesentlichen ETL Funktionalitäten konzentrieren. Eine schnelle Transformation von Daten zu jedem Zeitpunkt wird dadurch sehr einfach möglich. Durch den serverlosen Google Dataflow Dienst müssen wir uns auch nicht um die skalieren von mehrern Servern kümmern und zahlen auch keine Gebühren, wenn kein Jobs läuft. Dataflow skaliert bis auf 0 herunter.