8 min read

Komplexität überbrücken: Migration von Hive UDFs zu BigQuery Remote Functions - Teil 2

Published on
February 28, 2024
Author
Csaba Kassai
Csaba Kassai
Head of Data
Subscribe to our newsletter
Subscribe
Komplexität überbrücken: Migration von Hive UDFs zu BigQuery Remote Functions - Teil 2

In der vorigen Teil haben wir uns mit der Migration komplexer Hive UDFs, wie dem 'xml_product_info_extractor', zu BigQuery Remote Functions beschäftigt. Dieser Ansatz ermöglicht es Ihnen, vorhandenen Java-Code innerhalb einer Cloud Function zu nutzen, was eine nahtlose Integration mit der SQL-Umgebung von BigQuery ermöglicht. Um die Zuverlässigkeit und Leistung Ihrer Funktion sicherzustellen, sind jedoch gründliche Tests und Best Practices für die Bereitstellung erforderlich. Dieser Teil befasst sich mit diesen wichtigen Aspekten und konzentriert sich auf die Wiederverwendung von vorhandenem Code für Tests und Bereitstellung mit Terraform.

Einheitliche Prüfung der UDF

Wenn Sie Glück haben und die Entwickler der ursprünglichen Hive UDF die Best Practices bei der Entwicklung befolgt haben, gibt es bereits einige Unit-Tests, die Sie wiederverwenden können. Diese Unit-Tests sind wertvolle Ressourcen, die die Testphase der Migration erheblich verkürzen können. Mit einigen Anpassungen können diese Tests wiederverwendet werden, um die Funktionalität Ihrer Cloud-Funktion vor der Bereitstellung zu validieren. 

Hive UDF-Einheitstests

Hier ist ein praktisches Beispiel für einen Unit-Test für unsere Hive UDF, die XML-Daten verarbeitet. Dieser Test folgt der Standardstruktur, die Sie erwarten würden:

  1. Einrichtung: Wir beginnen mit der Erstellung einer Instanz unserer UDF unter Verwendung ihres Standardkonstruktors.
  2. Vorbereitung der Eingabe: Als Nächstes bereiten wir die Eingabe für unseren Test vor, indem wir eine XML-Datei aus unseren Ressourcen laden und so die Daten nachahmen, die unsere UDF in einem realen Szenario verarbeiten würde.
  3. Ausführung: Nachdem wir unser Setup fertiggestellt und die Eingaben vorbereitet haben, rufen wir die Evaluierungsmethode unserer UDF auf, in der die eigentliche Verarbeitung stattfindet.
  4. Verifizierung: Schließlich überprüfen wir das Ergebnis mit den Assert-Funktionen von jUnit, um sicherzustellen, dass die Ausgabe der UDF unseren Erwartungen entspricht.

Der Einfachheit halber konzentriert sich dieses Beispiel auf einen einzigen Testfall, aber normalerweise würden Sie mehrere Tests durchführen, um verschiedene Szenarien abzudecken. Der vollständige Quellcode für diese Tests ist hier verfügbar. Dieses Beispiel demonstriert einen einfachen Ansatz zum Testen von Hive UDFs, um sicherzustellen, dass sie in verschiedenen Fällen korrekt funktionieren.

Testen der BigQuery UDF-Cloud-Funktionen

Die Beibehaltung der Java-Sprache für unsere BigQuery UDF ermöglicht es uns, bestehende Testfälle aus der Hive UDF mit minimalen Anpassungen wiederzuverwenden. Bei diesem praktischen Ansatz wird der Testcode so verfeinert, dass er in den Rahmen der Cloud-Funktion passt, während die zentrale Testlogik erhalten bleibt:

  1. Einrichten: Zur Initialisierung instanziieren wir unsere Cloud Function-Klasse, ähnlich wie beim Einrichten der Hive UDF.
  2. Vorbereitung der Eingabe: Es werden dieselben XML-Daten aus unseren Testressourcen verwendet, aber dieses Mal formatieren wir sie in JSON-Objekte, die unsere Cloud-Funktion erwartet.
  3. Ausführung: Die Prozessmethode wird mit unseren vorbereiteten Eingaben aufgerufen, wodurch die Ausführung der Funktion so nachgebildet wird, wie sie in einer realen Umgebung erfolgen würde.
  4. Verifizierung: Der Verifizierungsschritt entspricht unserem ursprünglichen Ansatz, bei dem die Korrektheit der Funktionsausgabe anhand der erwarteten Werte überprüft wird.

Der vollständige Code für diese angepassten Tests ist hier zugänglich. Dieser Ansatz unterstreicht die Effizienz der Nutzung bestehender Tests mit nur den notwendigen Änderungen für die Cloud Function und gewährleistet einen reibungslosen Übergang der Funktionalität Ihrer UDF zu BigQuery mit minimalem Aufwand.

Bereitstellung auf GCP

Damit unsere UDF in BigQuery funktioniert, müssen wir zwei Schlüsselkomponenten bereitstellen. Die erste ist die Cloud Function, die den erforderlichen HTTP-Endpunkt für den Zugriff durch BigQuery erstellt. Dieser Schritt ist entscheidend, damit die Logik unserer UDF außerhalb der nativen Umgebung von BigQuery ausgeführt werden kann. Die zweite Komponente ist die BigQuery Remote Function-Definition, die BigQuery im Wesentlichen mitteilt, wie die Cloud Function zu finden und zu verwenden ist. Durch das Einrichten dieser beiden Elemente verbinden wir BigQuery mit unserer externen UDF und machen sie für die Verwendung in unseren Datenverarbeitungs-Workflows bereit.

Cloud-Funktionen

Die Bereitstellung der Cloud-Funktion umfasst eine Reihe praktischer Schritte, angefangen von der Paketierung der Funktion bis hin zu ihrer Bereitstellung über Terraform. Zunächst erstellen wir mit Maven ein Uber-Jar, um die Funktion zusammen mit ihren Abhängigkeiten zu bündeln und sicherzustellen, dass sie in sich geschlossen ist. Dazu fügen Sie das Maven Assembly Plugin zu Ihrer pom.xml hinzu und konfigurieren es, um ein uber-jar zu erstellen:

Durch die Einbindung dieses Plugins in Ihre pom.xml-Datei wird Maven so konfiguriert, dass während des Build-Prozesses eine zusätzliche jar-Datei erzeugt wird. Diese Datei, die sich durch das Suffix -jar-with-dependencies in ihrem Namen auszeichnet, kapselt alle notwendigen Abhängigkeiten und ist somit ideal für die Bereitstellung. Nach der Erstellung des uber-jar muss dieses jar in eine Zip-Datei komprimiert werden, was mit einem einfachen Zip-Befehl leicht zu bewerkstelligen ist. Dieser Schritt bereitet die Jar-Datei für den Upload vor und stellt sicher, dass sie für die Bereitstellung korrekt verpackt ist.

Nach dem Komprimieren wird die Datei in den Cloud-Speicher hochgeladen, was mit dem Befehl "gcloud storage cp" erreicht werden kann:

Hier ist das vollständige Shell-Skript, mit dem diese Schritte ausgeführt werden können. 

Nachdem der Code der Funktion sicher im Cloud Storage gespeichert wurde, besteht der letzte Schritt darin, die Cloud Function mit Terraform bereitzustellen. Definieren Sie in Ihrer Terraform-Konfiguration die Ressource Cloud Function und geben Sie dabei den Cloud Storage Bucket und den Pfad der Zip-Datei als Quelle an. Hier ist ein Beispiel für ein Terraform-Snippet:

Durch die Ausführung von "terraform apply" wird die Cloud-Funktion bereitgestellt, so dass sie als HTTP-Endpunkt zugänglich und für die Integration als BigQuery Remote Function bereit ist. Dieser rationalisierte Prozess stellt sicher, dass Ihre Funktion mit allen notwendigen Abhängigkeiten bereitgestellt wird und bereit ist, Ihre BigQuery-Daten-Workflows mit benutzerdefinierter Logik zu erweitern.

BigQuery-Fern-UDF

Nach der erfolgreichen Bereitstellung unserer Cloud Function besteht der nächste wichtige Schritt darin, die BigQuery-Umgebung so zu konfigurieren, dass die neu bereitgestellte UDF in SQL-Abfragen verwendet werden kann. Diese doppelte Einrichtung umfasst die Einrichtung einer sicheren Verbindung zur Cloud Function und die Definition der UDF in BigQuery.

Herstellen einer Verbindung zu Cloud-Funktionen

Um die Kommunikation zwischen BigQuery und der Cloud Function zu erleichtern, erstellen wir zunächst eine BigQuery-Verbindungsressource. Diese Verbindung dient als sichere Leitung, über die BigQuery Daten an die Cloud-Funktion senden und Ergebnisse von ihr empfangen kann.

In der Terraform-Konfiguration wird die Ressource "google_bigquery_connection" definiert, um diese Verbindung herzustellen. Hier geben wir eine eindeutige connection_id, die Google Cloud Project id und den geografischen Standort an, an dem die Cloud Function bereitgestellt wird. Der cloud_resource-Block bedeutet, dass diese Verbindung zu einer Cloud-Ressource besteht, in unserem Fall zu einer Cloud-Funktion.
Mit der Verbindung wird ein dediziertes Service-Konto erstellt und dieses Service-Konto muss die Cloud Run Invoker Rolle haben, um auf den API-Endpunkt zugreifen zu können. Wir können die Terraform-Ressource "google_project_iam_member" verwenden, um diese Rolle zu gewähren.

Erstellen der BigQuery UDF-Definition

Nachdem die Verbindung hergestellt ist, wird die BigQuery-UDF selbst definiert. Dies beinhaltet die Angabe des UDF-Namens, der Cloud-Funktion, die sie aufrufen soll (identifiziert durch ihren Endpunkt), sowie der Parameter und des Rückgabetyps der Funktion.

Die UDF-Definition wird mithilfe der Data Definition Language (DDL) von BigQuery innerhalb einer google_bigquery_job-Ressource formuliert. Dieser Job führt eine DDL-Abfrage aus, die die UDF in BigQuery erstellt oder ersetzt und sie über die zuvor hergestellte Verbindung mit der Cloud-Funktion verknüpft. Die OPTIONS-Klausel in der DDL-Anweisung gibt den Endpunkt der Cloud Function an und stellt sicher, dass BigQuery weiß, wohin es die Daten zur Verarbeitung senden soll.

Im Terraform-Skript werden Locals verwendet, um die Definition der UDF-Eigenschaften zu organisieren und zu vereinfachen, z. B. den Namen (udf_name), den Einstiegspunkt in die Cloud Function (udf_entry_point) und den Cloud Storage Bucket, in dem sich der Code der Cloud Function befindet (udf_archive_bucket). Die ddl_query local konstruiert die DDL-Anweisung unter Verwendung dieser Eigenschaften.

Sie können den vollständigen Terraform-Code hier finden. Diese Terraform-Konfiguration definiert nicht nur die UDF innerhalb von BigQuery, sondern stellt auch sicher, dass sie eng mit der Cloud Function integriert ist, was eine nahtlose Datenverarbeitung ermöglicht. Durch die Ausführung der Terraform-Anwendung werden diese Ressourcen bereitgestellt, und die UDF steht für die Verwendung in BigQuery-Abfragen zur Verfügung, wodurch die Lücke zwischen Ihren komplexen Datenverarbeitungsanforderungen und den leistungsstarken Analysefunktionen von BigQuery geschlossen wird.

Nach der erfolgreichen Bereitstellung kann die UDF in SQL verwendet werden:

Nächster Punkt: Datenvalidierung während eines DWH-Migrationsprojekts

Mit diesem umfassenden Leitfaden zur Migration komplexer Hive UDFs zu BigQuery Remote Functions schließen wir unsere detaillierte Untersuchung zur Erweiterung der BigQuery-Funktionen mit externer benutzerdefinierter Logik ab. In dieser Serie haben wir die Feinheiten der Übertragung der reichhaltigen Funktionalität der Hive UDFs erkundet und ihre Leistung und Zuverlässigkeit in einer Cloud-nativen Umgebung mit Hilfe von Cloud Functions und Terraform sichergestellt. Der Weg von der Erkenntnis, dass eine Migration notwendig ist, über das Testen bis hin zur endgültigen Bereitstellung zeigt einen klaren Weg für die Nutzung von bestehendem Code und Tests, wodurch der Migrationsprozess rationalisiert wird.

Zum Abschluss dieses Kapitels über die Migration benutzerdefinierter Funktionen werfen wir einen Blick auf einen weiteren wichtigen Aspekt von Data Warehouse-Migrationsprojekten: die Datenvalidierung. Die Gewährleistung der Genauigkeit und Konsistenz Ihrer Daten nach der Migration ist für die Aufrechterhaltung der Integrität Ihrer analytischen Workflows von größter Bedeutung. In unserer nächsten Serie werden wir uns mit Strategien und Tools für eine effektive Datenvalidierung befassen, die Ihnen helfen, das Vertrauen in Ihre migrierten Daten zu sichern und Ihre Entscheidungsprozesse zu optimieren. Bleiben Sie dran für aufschlussreiche Diskussionen über die Sicherung der Datenqualität in Ihrem nächsten großen Migrationsprojekt.

Author
Csaba Kassai
Head of Data
Subscribe to our newsletter
Subscribe