8 min read

Häufige Fehler bei der Migration von HiveQL zu BigQuery: Eine detaillierte Untersuchung Teil 1

Published on
March 12, 2024
Author
Steve Ahlswede
Steve Ahlswede
Data Engineer
Subscribe to our newsletter
Subscribe
Häufige Fehler bei der Migration von HiveQL zu BigQuery: Eine detaillierte Untersuchung Teil 1

Willkommen zum zweiten Teil unserer Serie über Datenvalidierung bei Data-Warehouse-Migrationen. In unserem letzten Beitrag haben wir einen allgemeinen Überblick über den Datenvalidierungsprozess gegeben, seine Bedeutung für einen nahtlosen Übergang zwischen Plattformen beleuchtet und die grundlegenden Schritte und Strategien erläutert. Darauf aufbauend konzentrieren wir uns nun auf einige praktische Erfahrungen mit der Datenvalidierung am Beispiel von HiveQL to BigQuery als Fallstudie.

An diesem Punkt Ihrer Datenmigration sollten Sie die SQL-Dateien Ihrer Datenpipeline bereits vom Quelldialekt in den Zieldialekt übersetzt haben. Von hier aus können Sie sowohl die ursprünglichen als auch die migrierten Pipelines ausführen. Wie in unserem vorherigen Beitrag erwähnt, ziehen wir es vor, den Datenvergleich durchzuführen, indem wir beide Tabellen entweder im Quell- oder im Zielsystem haben. Da wir hier über Hive zu BigQuery sprechen, bedeutet dies, dass Sie Ihre Hive-Tabelle zu BigQuery hochladen (oder umgekehrt, wenn Sie dies bevorzugen). Jetzt können Sie mit der Validierung beginnen! Gehen wir nun einige der häufigsten Fehler durch, die uns bei einem kürzlich durchgeführten Migrationsprojekt aufgefallen sind.

Fehler bei TRIM

Die Funktion "TRIM()" scheint eine einfach zu übersetzende Funktion zu sein, da sich die Funktionen in den allermeisten Fällen gleich zu verhalten scheinen. Die Hive-Funktion gibt jedoch an, dass sie führende und nachfolgende Leerzeichen aus dem String entfernt, während die BigQuery-Version der Funktion Whitespaces. Das bedeutet, dass das BigQuery TRIM Leerzeichen, Zeilenumbrüche, vertikale Tabulatoren usw. entfernt. Für das bloße Auge sehen die Daten gleich aus, aber die feinen Unterschiede sollten auf die eine oder andere Weise von Ihrem Validierungstool/Ihrer Abfrage erfasst werden. Die TRIM-Funktion in BigQuery bietet die Möglichkeit, eine bestimmte Gruppe von zu entfernenden Zeichen anzugeben. Wenn Sie dies auf `" "` setzen, können Sie das Verhalten der TRIM-Funktion von Hive nachahmen.

Fehler im Ranking

Einer der häufigsten Fehler, auf die wir gestoßen sind, sind diejenigen, die sich aus der Verwendung von `ROW_NUMBER() OVER()` ergeben, um eine Rangfolge der Zeilen auf der Grundlage einiger Feldwerte zu erstellen. Die BigQuery- und die Hive-Syntax sind für diesen Zweck identisch. Das Problem tritt jedoch auf, wenn die für die Rangfolge verwendeten Felder in den Zeilenpartitionen nicht eindeutig sind. In diesen Fällen kann es vorkommen, dass mehrere Zeilen denselben Wert für das Ranking-Feld haben. Beispiel: Sie sortieren die "Namen" der Schüler nach ihren "Noten" in einer bestimmten Klasse. Wenn Sie zwei oder mehr Schüler mit genau der gleichen Note haben, führt die Verwendung von `ROW_NUMBER` dazu, dass die gleichrangigen Schüler auf der Grundlage einer zugrundeliegenden Umordnung der Daten sortiert werden. In diesem Fall liefern Hive und BQ nicht das gleiche Ergebnis. Um die Validierung durchzuführen, müssen Sie weitere Felder hinzufügen, die für die Sortierung verwendet werden, bis Sie genügend Felder haben, um eine eindeutige Rangfolge für jeden Schüler zu erhalten. Vielleicht können die Namen der Schüler dann als sekundärer Faktor in der Rangliste verwendet werden, so dass die Noten immer noch der primäre Faktor sind, aber wenn eine Note gleich ist, werden die Schüler auf der Grundlage der alphabetischen Reihenfolge ihrer Namen sortiert. Dies kann natürlich zu Verzerrungen führen, die zu unerwünschten Ergebnissen in Ihren Daten führen können, und daher sollte die Bestimmung dieser zusätzlichen Faktoren gut überlegt sein. Da dies nur für den Zeitraum der Validierung erforderlich ist, können Sie auch zur ursprünglichen Rangfolge zurückkehren, sobald Sie sicher sind, dass die migrierten Daten der Tabelle gültig sind.

Fehler mit NULL-Array-Größe

Die Hive-Funktion `SIZE` wird verwendet, um die Anzahl der Elemente innerhalb eines Arrays zu ermitteln. Das BigQuery-Gegenstück ist `ARRAY_LENGTH`. Beide funktionieren genau gleich, außer wenn man NULL-Werte als Eingabe erhält. In solchen Fällen gibt die ARRAY_LENGTH-Funktion NULL zurück, während die Hive-Funktion -1 zurückgibt. Wir haben festgestellt, dass dies zu Unterschieden in den Ergebnissen von `WHERE`-Klauseln führt, die auf `WHERE SIZE(array) < 100` prüfen, da der Hive-Code immer noch Zeilen auswählt, in denen das Array aufgrund von `-1 < 100` NULL ist, während der BigQuery-Code dies nicht tut, da `NULL < 100` nicht als `TRUE` ausgewertet wird. In diesem Fall können Sie eine temporäre CASE-Funktion in BigQuery erstellen, die alle NULL-Arrays auf `-1` abbildet.

Fehler in Unix-Zeitkonvertierungen

Das nächste Problem erforderte einige Nachforschungen, um die Ursache aufzudecken. Wir arbeiteten mit Publikationsdaten, die bis zu sehr frühen wissenschaftlichen Arbeiten aus dem 16. Jahrhundert zurückreichten. Jahrhundert zurückreichten. Hier hatten wir eine Pipeline, die Unix-Zeitstempel als Eingaben verwendete und sie in einen für Menschen lesbaren Zeitstempel umwandelte. Dies funktionierte bis auf einige wenige Zeilen, in denen der Unix-Zeitstempel z. B. `-17429212800` lautete, problemlos. In diesem Fall wurde genau derselbe Unix-Zeitstempel als Eingabe für die jeweiligen Funktionen zur Umwandlung in einen Zeitstempel verwendet (`FROM_UNIXTIME` in Hive und `TIMESTAMP_SECONDS` in BigQuery). Die Werte, die sich aus diesen beiden Funktionen ergaben, lagen jedoch neun Tage auseinander und ergaben `1417-01-01 00:00:00` in Hive und `1417-09-10 00:00:00` in BigQuery. Bei moderneren Datumsangaben (z. B. `2012-10-13`) trat dieses Problem nicht auf, ebenso wenig bei Datumsangaben wie `1600-01-01`, so dass wir versuchten, das Datum zu ermitteln, bei dem wir eine Abweichung feststellen konnten. Schließlich identifizierten wir den genauen Unix-Zeitstempel, an dem der Sprung von neun Tagen auftrat: von `-12219212800` zu `-12219312800`, wobei ersteres dem `1582-10-15` und letzteres dem `1582-10-04` in Hive entspricht. In BigQuery verursachten diese beiden Zeitstempel keinen Sprung und waren einfach aufeinanderfolgende Tage (1582-10-15 und 1582-10-14). Zu diesem Zeitpunkt war ich immer noch etwas verwirrt und wollte dies schon als Fehler in Hive abtun. Ein Kollege klärte mich jedoch auf und erklärte mir, dass diese Zeit der gregorianischen Kalenderreform entspricht, bei der zwischen `1582-10-04` und `1582-10-15` keine Tage liegen. Hive folgt also dem gregorianischen Kalender, während BigQuery den proleptischen gregorianischen Kalender für Daten vor "1582-10-15" verwendet. Das ist eine interessante Erkenntnis, aber wie haben wir das bei der Validierung gehandhabt? Nun, es gab mehrere Möglichkeiten, die wir hätten nutzen können. Eine Möglichkeit war die Erstellung einer "CASE"-Anweisung in BigQuery, bei der wir neun Tage vom Zeitstempel abziehen, wenn dieser vor dem 1582-10-15 liegt. Nach Rücksprache mit dem Kunden entschieden wir jedoch, dass es ausreicht, Zeilen mit Zeitstempeln vor diesem Datum aus der Validierung herauszufiltern. Hätten diese Zeitstempel eine größere Auswirkung auf nachgelagerte Tabellen, z. B. in einer `WHERE`-Klausel, dann hätte das Belassen der Inkonsistenzen in der Tabelle zu mehr Kopfzerbrechen geführt, und in einem solchen Fall würden wir die Lösung mit der `CASE`-Anweisung empfehlen. 

Einpacken

Ich denke, dass wir an dieser Stelle einige sehr interessante Themen behandelt haben, aber um Sie nicht mit zu viel auf einmal zu überwältigen, werde ich dieses Thema in zwei Teile aufteilen und die restlichen Informationen im zweiten Teil dieses Beitrags mitteilen. Ich hoffe, dass diese wenigen Beispiele Ihnen bereits eine Hilfe sein können, oder zumindest hoffe ich, dass es eine interessante Lektüre war. Bis bald im nächsten Beitrag!

Author
Steve Ahlswede
Data Engineer
Subscribe to our newsletter
Subscribe