In der stetig wachsenden Welt der Big Data stellt die Verwaltung und Organisation großer Datenmengen eine bedeutende Herausforderung dar. Für Big Data Unternehmen, die mit Data-Lakes arbeiten, ist die Auswahl des richtigen Tabellenformats eine wichtige Entscheidung. Klassische Datenformate wie Parquet, Avro oder ORC bieten viele Vorteile, haben aber auch einige Schwachstellen:
- Die Datenkonsistenz ist nicht gewährleistet; ACID Transaktionen sind nicht möglich.
- Das Ändern des Schemas einer Tabelle bedingt das komplette Prozessieren der enthaltenen Daten.
- Daten können nicht versioniert werden. Updates und Deletes einzelner Datensätze sind je nach Format nicht möglich.
- Eine inkrementelle Verarbeitung bedarf zusätzlicher ELT Logik.
Apache Iceberg, ein Open-Source-Tabellenformat, hat sich als vielversprechende Lösung für die Vereinfachung und Optimierung der Data-Lake-Verwaltung etabliert. Iceberg wurde so designed, dass die oben genannten Schwachstellen nicht zutreffen. Mit seinen einzigartigen Designprinzipien und leistungsstarken Funktionen bietet Apache Iceberg eine verbesserte Skalierbarkeit, Zuverlässigkeit und Abfrageleistung. In diesem Blogbeitrag werden wir uns der Welt von Apache Iceberg widmen und seine Kernkonzepte, wichtigen Funktionen sowie die Vorteile, die es für moderne Data Lake Organisationen mit sich bringt, betrachten.
Die Kernkonzepte von Apache Iceberg
Ursprünglich wurde Iceberg von Netflix entwickelt, um ein geeignetes Format für ihre Petabyte grossen Tabellen zu schaffen. 2018 wurde es an die open-source Apache Software Foundation gespendet. Es bietet dabei einen neuartigen Ansatz zur Verwaltung von Daten in verteilten Speichersystemen bzw. Data Lakes.
Im Wesentlichen wurden bei der Entwicklung von Iceberg drei grundlegende Konzepte umgesetzt:
1. Tabellen: Iceberg-Tabellen dienen als logische Container zur Organisation von Daten. Die eigentlichen Daten sind in Formaten wie Avro, Parquet oder ORC abgelegt. Zusätzlich gibt es Schema und Metadaten, um einen effizienten Datenzugriff und Manipulationen zu ermöglichen.
2. Snapshots: Snapshots sind unveränderliche Momentaufnahmen von Tabellen zu einem bestimmten Zeitpunkt. Sie gewährleisten konsistente und zuverlässige Ansichten der Daten, um historische Daten präzise abfragen zu können. Daraus ergibtsich eine Zeitreise-Funktionalität, die mit den klassischen Datenformaten nicht direkt umsetzbar ist.
3. Manifeste: Manifeste fungieren als transaktionale Protokolle und erfassen Metadatenänderungen für jede Snapshot-Version. Sie ermöglichen eine effiziente Schemaentwicklung und vereinfachen Aktualisierungen des Schemas, ohne dass gesamte Datensätze neu geschrieben werden müssen.
Vorteile für datengetriebene Organisationen
Die Implementierung von Apache Iceberg bringt zahlreiche Vorteile für datengetriebene Organisationen mit sich, darunter:
- Skalierbarkeit und Leistung: Icebergs Designprinzipien wie versteckte Partitionierung, Predicate-Pushdown und Abfragen über Metadaten ermöglichen effiziente Datenverarbeitung im großen Maßstab.
- ACID Datenoperationen: Inkrementelle Schreibvorgänge machen Iceberg ACID konform. Die transaktionale Datenkonsistenz wird über Metadaten bzw. deren Snapshots sichergestellt.
- Kompatibilität mit Data Lakes und Data Lake Engines: Apache Iceberg fördert die Interoperabilität, indem es Kompatibilität mit verschiedenen Speichersystemen wie dem Apache Hadoop Distributed File System (HDFS), Amazon S3 und Azure Blob Storage bietet. Es ermöglicht nahtlose Datenportabilität und herstellerunabhängige Lösungen. Zudem wird es von Data Lake Engines wie Spark, Hive, Dremio und Trino unterstützt.
Wichtige Funktionen
Apache Iceberg bietet eine Vielzahl von Funktionen, die es zu einer leistungsstarken Wahl für die Verwaltung von Data Lakes machen. Zu den bemerkenswerten Funktionen gehören:
Datenversionierung und Zeitreisen
Iceberg ermöglicht effiziente zeitorientierte Abfragen durch die Nutzung von Snapshot-Versionen. Benutzer können problemlos auf einen Datenstand zurückgreifen, der zu einem bestimmten Zeitpunkt gültig war.
Folgendes Code-Beispiel soll verschiedene Funktionalitäten des Zeitreise-Features mit Spark veranschaulichen. Zunächst erstellen wir mit einer laufenden Spark-Session ein Test-Dataframe und lassen uns dieses anzeigen:
test_df = spark.createDataFrame(([1, "data1"], [2, "data2"]), ["id", "data"])
test_df.show()
Wir erstellen für dieses Test-Dataframe eine Iceberg-Tabelle in der Datenbank «test» unseres Hive-Metastores. Die physischen Daten liegen dabei am angegebenen Ort (location – hier S3):
test_df.writeTo("test.test_iceberg")
.tableProperty("location", "s3a://my-s3-bucket/test/test_iceberg/")
.createOrReplace()
Über die Metatabelle “snapshots” können wir uns den gerade geschriebenen Snapshot anzeigen lassen:
spark.table("test.test_iceberg.snapshots").show(truncate=False)
Wir erstellen ein Dataframe mit einer neuen Zeile und fügen diese an die bestehende Iceberg Tabelle im Append-Modus an:
updated_test_df = spark.createDataFrame(([3, "data3"],), ["id", "data"])
updated_test_df.writeTo("test.test_iceberg").append()
spark.table("test.test_iceberg").show()
Nun wurde ein zweiter Snapshot erstellt:
spark.table("test.test_iceberg.snapshots").show(truncate=False)
Generell wird in Iceberg bei jedem Schreib- und Löschvorgang ein Snapshot geschrieben. Durch das Zeitreise-Feature können wir uns nun den ursprünglichen Snapshot mittels Snapshot-Id anzeigen lassen:
spark.read.format("iceberg")
.option("snapshot-id", "6206560893307242291")
.load("test.test_iceberg").show()
Weiterhin kann man auch eine Start- und eine End-Snapshot-Id angeben und somit z.B. einen Delta-Load mit allen Daten zwischen dem letzten und dem aktuellen Snapshot machen:
spark.read.format("iceberg").option("start-snapshot-id", "6206560893307242291")
.option("end-snapshot-id", "800859421853620168")
.load("test.test_iceberg")
Zudem gibt es noch die Möglichkeit Snapshots ablaufen zu lassen bzw. zu löschen. Zum Testen wurde noch eine Zeile bzw. Snapshot hinzugefügt:
Nun möchten wir alle Snapshots, die älter als der gegebene Zeitstempel sind, löschen. Dies geschieht über den Aufruf einer Prozedur durch Spark SQL:
spark.sql("CALL system.expire_snapshots('test.test_iceberg', TIMESTAMP '2023-06-24 17:24:00.000')")
Auch das Zurückkehren zu einem bestimmten Snapshot wird über die „rollback_to_snapshot“-Prozedur ermöglicht:
spark.sql("CALL system.rollback_to_snapshot('test.test_iceberg', 800859421853620168)")
Schemaentwicklung
Iceberg vereinfacht die Entwicklung des Schemas, indem inkrementelle Änderungen an den Metadaten ermöglicht werden, ohne die vorhandenen Daten zu beeinträchtigen. Die folgenden Operationen werden dabei aktuell (Iceberg 1.3.0) unterstützt:
- Add: Hinzufügen einer neuen Spalte oder eines verschachtelten Structs. Dies kann über Spark SQL umgesetzt werden:
spark.sql("ALTER TABLE test.test_iceberg ADD COLUMN (new_column string)")
Die nächsten Operationen können ebenso über Spark SQL ausgeführt werden.
- Drop: Entfernen einer existierenden Spalte.
- Rename: Umbenennen einer existierenden Spalte.
- Update: Erweitern des Typs einer Spalte, eines Struct-Feldes, eines Map-Schlüssels oder ‑Wertes oder eines Listenelements.
- Reorder: Verändern der Reihenfolge der Spalten.
Inkrementelle Schreibvorgänge
Iceberg optimiert Datenzugriffe durch die Verwendung von dateibasierten Transaktionen und ermöglicht atomare Commits. Es gewährleistet Konsistenz und Zuverlässigkeit und minimiert den Einfluss von gleichzeitigen Schreibvorgängen. Durch das Konzept vom isolierten Lesen und Schreiben können bspw. verschiedene Data-Lake-Engines wie Spark, Hive, Dremio oder Trino gleichzeitig Schreibvorgänge auf derselben Tabelle ausführen.
Partitionen und Partitionsentwicklung
Nicht nur Schemata, sondern auch Partitionen können in Iceberg angepasst werden. Im Gegensatz zur Partitionierung in Hive, sind in Iceberg die Partitionen versteckt, welches nicht nur effizientere Abfragen, sondern auch eine Partitionsentwicklung ermöglicht. Eine solche Anpassung der Partitionen kann erforderlich sein, wenn sich z.B. das Datenvolumen ändert und somit die Granularität der Partition oder die zu partitionierende Spalte angepasst werden. In Abbildung 1 ändert sich die Partitionierung von Monat zu Tag. Die alten Daten bleiben dabei je Monat partitioniert, während die neuen Daten pro Tag partitioniert werden. Es werden nur die Metadaten angepasst – die eigentlichen Datendateien bleiben unverändert.
Effiziente Abfragen
Iceberg nutzt Predicate-Pushdown und metadatengetriebene Spaltenauswahltechniken, um die Abfrageleistung zu optimieren. Konkret wird beim Predicate-Pushdown das Hive SQL WHERE-Statement direkt auf das Iceberg-TableScan-Level sowie auf die Parquet- und ORC-Lesevorgänge gepusht. Dadurch werden nur die Dateien angefasst, die effektiv die gewünschten Daten enthalten. Dies ermöglicht schnelleren und effizienteren Datenzugriff, was Iceberg für Echtzeitanalyse und interaktive Abfragen geeignet macht.
Fazit
Apache Iceberg revolutioniert die Verwaltung von Data Lakes, indem es eine robuste, skalierbare und leistungsstarke Lösung für die Organisation und Abfrage von Big Data bietet. Seine innovativen Designprinzipien, leistungsstarken Funktionen und nahtlose Integration mit gängigen Big-Data-Frameworks machen Apache Iceberg zu einem wichtigen Datenformat für datengetriebene Organisationen. Es ermöglicht, das volle Potenzial eines Data Lakes ausschöpfen zu können und gleichzeitig nicht auf die Vorteile traditioneller DWH-Lösungen verzichten zu müssen.
Erfahren Sie hier mehr über Lösungen im Bereich Data Management oder besuchen Sie eines unserer kostenlosen Webinare.