In der ste­tig wach­sen­den Welt der Big Data stellt die Ver­wal­tung und Orga­ni­sa­tion gro­ßer Daten­men­gen eine bedeu­tende Her­aus­for­de­rung dar. Für Big Data Unter­neh­men, die mit Data-Lakes arbei­ten, ist die Aus­wahl des rich­ti­gen Tabel­len­for­mats eine wich­tige Ent­schei­dung. Klas­si­sche Daten­for­mate wie Par­quet, Avro oder ORC bie­ten viele Vor­teile, haben aber auch einige Schwachstellen:

  • Die Daten­kon­sis­tenz ist nicht gewähr­leis­tet; ACID Trans­ak­tio­nen sind nicht möglich.
  • Das Ändern des Sche­mas einer Tabelle bedingt das kom­plette Pro­zes­sie­ren der ent­hal­te­nen Daten.
  • Daten kön­nen nicht ver­sio­niert wer­den. Updates und Dele­tes ein­zel­ner Daten­sätze sind je nach For­mat nicht möglich.
  • Eine inkre­men­telle Ver­ar­bei­tung bedarf zusätz­li­cher ELT Logik.

Apa­che Ice­berg, ein Open-Source-Tabel­len­for­mat, hat sich als viel­ver­spre­chende Lösung für die Ver­ein­fa­chung und Opti­mie­rung der Data-Lake-Ver­wal­tung eta­bliert. Ice­berg wurde so desi­gned, dass die oben genann­ten Schwach­stel­len nicht zutref­fen. Mit sei­nen ein­zig­ar­ti­gen Design­prin­zi­pien und leis­tungs­star­ken Funk­tio­nen bie­tet Apa­che Ice­berg eine ver­bes­serte Ska­lier­bar­keit, Zuver­läs­sig­keit und Abfra­geleis­tung. In die­sem Blog­bei­trag wer­den wir uns der Welt von Apa­che Ice­berg wid­men und seine Kern­kon­zepte, wich­ti­gen Funk­tio­nen sowie die Vor­teile, die es für moderne Data Lake Orga­ni­sa­tio­nen mit sich bringt, betrachten.

Die Kern­kon­zepte von Apa­che Iceberg

Ursprüng­lich wurde Ice­berg von Net­flix ent­wi­ckelt, um ein geeig­ne­tes For­mat für ihre Peta­byte gros­sen Tabel­len zu schaf­fen. 2018 wurde es an die open-source Apa­che Soft­ware Foun­da­tion gespen­det. Es bie­tet dabei einen neu­ar­ti­gen Ansatz zur Ver­wal­tung von Daten in ver­teil­ten Spei­cher­sys­te­men bzw. Data Lakes.

Im Wesent­li­chen wur­den bei der Ent­wick­lung von Ice­berg drei grund­le­gende Kon­zepte umgesetzt:

1. Tabel­len: Ice­berg-Tabel­len die­nen als logi­sche Con­tai­ner zur Orga­ni­sa­tion von Daten. Die eigent­li­chen Daten sind in For­ma­ten wie Avro, Par­quet oder ORC abge­legt. Zusätz­lich gibt es Schema und Meta­da­ten, um einen effi­zi­en­ten Daten­zu­griff und Mani­pu­la­tio­nen zu ermöglichen.

2. Snapshots: Snapshots sind unver­än­der­li­che Moment­auf­nah­men von Tabel­len zu einem bestimm­ten Zeit­punkt. Sie gewähr­leis­ten kon­sis­tente und zuver­läs­sige Ansich­ten der Daten, um his­to­ri­sche Daten prä­zise abfra­gen zu kön­nen. Dar­aus ergibt­sich eine Zeit­reise-Funk­tio­na­li­tät, die mit den klas­si­schen Daten­for­ma­ten nicht direkt umsetz­bar ist.

3. Mani­feste: Mani­feste fun­gie­ren als trans­ak­tio­nale Pro­to­kolle und erfas­sen Meta­da­ten­än­de­run­gen für jede Snapshot-Ver­sion. Sie ermög­li­chen eine effi­zi­ente Sche­ma­ent­wick­lung und ver­ein­fa­chen Aktua­li­sie­run­gen des Sche­mas, ohne dass gesamte Daten­sätze neu geschrie­ben wer­den müssen.

Vor­teile für daten­ge­trie­bene Organisationen

Die Imple­men­tie­rung von Apa­che Ice­berg bringt zahl­rei­che Vor­teile für daten­ge­trie­bene Orga­ni­sa­tio­nen mit sich, darunter:

  • Ska­lier­bar­keit und Leis­tung: Ice­bergs Design­prin­zi­pien wie ver­steckte Par­ti­tio­nie­rung, Pre­di­cate-Push­down und Abfra­gen über Meta­da­ten ermög­li­chen effi­zi­ente Daten­ver­ar­bei­tung im gro­ßen Maßstab.
  • ACID Daten­ope­ra­tio­nen: Inkre­men­telle Schreib­vor­gänge machen Ice­berg ACID kon­form. Die trans­ak­tio­nale Daten­kon­sis­tenz wird über Meta­da­ten bzw. deren Snapshots sichergestellt.
  • Kom­pa­ti­bi­li­tät mit Data Lakes und Data Lake Engi­nes: Apa­che Ice­berg för­dert die Inter­ope­ra­bi­li­tät, indem es Kom­pa­ti­bi­li­tät mit ver­schie­de­nen Spei­cher­sys­te­men wie dem Apa­che Hadoop Dis­tri­bu­ted File Sys­tem (HDFS), Ama­zon S3 und Azure Blob Sto­rage bie­tet. Es ermög­licht naht­lose Daten­por­ta­bi­li­tät und her­stel­ler­un­ab­hän­gige Lösun­gen. Zudem wird es von Data Lake Engi­nes wie Spark, Hive, Dre­mio und Trino unterstützt.

Wich­tige Funktionen

Apa­che Ice­berg bie­tet eine Viel­zahl von Funk­tio­nen, die es zu einer leis­tungs­star­ken Wahl für die Ver­wal­tung von Data Lakes machen. Zu den bemer­kens­wer­ten Funk­tio­nen gehören:

Daten­ver­sio­nie­rung und Zeitreisen

Ice­berg ermög­licht effi­zi­ente zeit­ori­en­tierte Abfra­gen durch die Nut­zung von Snapshot-Ver­sio­nen. Benut­zer kön­nen pro­blem­los auf einen Daten­stand zurück­grei­fen, der zu einem bestimm­ten Zeit­punkt gül­tig war.

Fol­gen­des Code-Bei­spiel soll ver­schie­dene Funk­tio­na­li­tä­ten des Zeit­reise-Fea­tures mit Spark ver­an­schau­li­chen. Zunächst erstel­len wir mit einer lau­fen­den Spark-Ses­sion ein Test-Data­frame und las­sen uns die­ses anzeigen:

test_df = spark.createDataFrame(([1, "data1"], [2, "data2"]), ["id", "data"])
test_df.show()

Wir erstel­len für die­ses Test-Data­frame eine Ice­berg-Tabelle in der Daten­bank «test» unse­res Hive-Metasto­res. Die phy­si­schen Daten lie­gen dabei am ange­ge­be­nen Ort (loca­tion – hier S3):

test_df.writeTo("test.test_iceberg")
       .tableProperty("location", "s3a://my-s3-bucket/test/test_iceberg/")
       .createOrReplace()

Über die Meta­ta­belle “snapshots” kön­nen wir uns den gerade geschrie­be­nen Snapshot anzei­gen lassen:

spark.table("test.test_iceberg.snapshots").show(truncate=False)

Wir erstel­len ein Data­frame mit einer neuen Zeile und fügen diese an die bestehende Ice­berg 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 zwei­ter Snapshot erstellt:

spark.table("test.test_iceberg.snapshots").show(truncate=False)

Gene­rell wird in Ice­berg bei jedem Schreib- und Lösch­vor­gang ein Snapshot geschrie­ben. Durch das Zeit­reise-Fea­ture kön­nen wir uns nun den ursprüng­li­chen Snapshot mit­tels Snapshot-Id anzei­gen lassen:

spark.read.format("iceberg")
     .option("snapshot-id", "6206560893307242291")
     .load("test.test_iceberg").show()

Wei­ter­hin kann man auch eine Start- und eine End-Snapshot-Id ange­ben und somit z.B. einen Delta-Load mit allen Daten zwi­schen dem letz­ten und dem aktu­el­len 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ög­lich­keit Snapshots ablau­fen zu las­sen bzw. zu löschen. Zum Tes­ten wurde noch eine Zeile bzw. Snapshot hinzugefügt:

Nun möch­ten wir alle Snapshots, die älter als der gege­bene Zeit­stem­pel sind, löschen. Dies geschieht über den Auf­ruf einer Pro­ze­dur durch Spark SQL:

spark.sql("CALL system.expire_snapshots('test.test_iceberg', TIMESTAMP '2023-06-24 17:24:00.000')")

Auch das Zurück­keh­ren zu einem bestimm­ten Snapshot wird über die „rollback_to_snapshot“-Prozedur ermöglicht:

spark.sql("CALL system.rollback_to_snapshot('test.test_iceberg', 800859421853620168)")
Sche­ma­ent­wick­lung

Ice­berg ver­ein­facht die Ent­wick­lung des Sche­mas, indem inkre­men­telle Ände­run­gen  an den Meta­da­ten ermög­licht wer­den, ohne die vor­han­de­nen Daten zu beein­träch­ti­gen. Die fol­gen­den Ope­ra­tio­nen wer­den dabei aktu­ell (Ice­berg 1.3.0) unter­stützt:

  • Add: Hin­zu­fü­gen einer neuen Spalte oder eines ver­schach­tel­ten Structs. Dies kann über Spark SQL umge­setzt werden:
spark.sql("ALTER TABLE test.test_iceberg ADD COLUMN (new_column string)")

Die nächs­ten Ope­ra­tio­nen kön­nen ebenso über Spark SQL aus­ge­führt werden.

  • Drop: Ent­fer­nen einer exis­tie­ren­den Spalte.
  • Rename: Umbe­nen­nen einer exis­tie­ren­den Spalte.
  • Update: Erwei­tern des Typs einer Spalte, eines Struct-Fel­des, eines Map-Schlüs­sels oder ‑Wer­tes oder eines Listenelements.
  • Reor­der: Ver­än­dern der Rei­hen­folge der Spalten.
Inkre­men­telle Schreibvorgänge

Ice­berg opti­miert Daten­zu­griffe durch die Ver­wen­dung von datei­ba­sier­ten Trans­ak­tio­nen und ermög­licht ato­mare Com­mits. Es gewähr­leis­tet Kon­sis­tenz und Zuver­läs­sig­keit und mini­miert den Ein­fluss von gleich­zei­ti­gen Schreib­vor­gän­gen. Durch das Kon­zept vom iso­lier­ten Lesen und Schrei­ben kön­nen bspw. ver­schie­dene Data-Lake-Engi­nes wie Spark, Hive, Dre­mio oder Trino gleich­zei­tig Schreib­vor­gänge auf der­sel­ben Tabelle ausführen.

Par­ti­tio­nen und Partitionsentwicklung

Nicht nur Sche­mata, son­dern auch Par­ti­tio­nen kön­nen in Ice­berg ange­passt wer­den. Im Gegen­satz zur Par­ti­tio­nie­rung in Hive, sind in Ice­berg die Par­ti­tio­nen ver­steckt, wel­ches nicht nur effi­zi­en­tere Abfra­gen, son­dern auch eine Par­ti­ti­ons­ent­wick­lung ermög­licht. Eine sol­che Anpas­sung der Par­ti­tio­nen kann erfor­der­lich sein, wenn sich z.B. das Daten­vo­lu­men ändert und somit die Gra­nu­la­ri­tät der Par­ti­tion oder die zu par­ti­tio­nie­rende Spalte ange­passt wer­den. In Abbil­dung 1 ändert sich die Par­ti­tio­nie­rung von Monat zu Tag. Die alten Daten blei­ben dabei je Monat par­ti­tio­niert, wäh­rend die neuen Daten pro Tag par­ti­tio­niert wer­den. Es wer­den nur die Meta­da­ten ange­passt – die eigent­li­chen Daten­da­teien blei­ben unverändert.

Abbil­dung 1: Bei­spiel einer Par­ti­ti­ons­ent­wick­lung nach Datum
Effi­zi­ente Abfragen

Ice­berg nutzt Pre­di­cate-Push­down und meta­da­ten­ge­trie­bene Spal­ten­aus­wahl­tech­ni­ken, um die Abfra­geleis­tung zu opti­mie­ren. Kon­kret wird beim Pre­di­cate-Push­down das Hive SQL WHERE-State­ment direkt auf das Ice­berg-Tab­le­Scan-Level sowie auf die Par­quet- und ORC-Lese­vor­gänge gepusht. Dadurch wer­den nur die Dateien ange­fasst, die effek­tiv die gewünsch­ten Daten ent­hal­ten. Dies ermög­licht schnel­le­ren und effi­zi­en­te­ren Daten­zu­griff, was Ice­berg für Echt­zeit­ana­lyse und inter­ak­tive Abfra­gen geeig­net macht.

Fazit

Apa­che Ice­berg revo­lu­tio­niert die Ver­wal­tung von Data Lakes, indem es eine robuste, ska­lier­bare und leis­tungs­starke Lösung für die Orga­ni­sa­tion und Abfrage von Big Data bie­tet. Seine inno­va­ti­ven Design­prin­zi­pien, leis­tungs­star­ken Funk­tio­nen und naht­lose Inte­gra­tion mit gän­gi­gen Big-Data-Frame­works machen Apa­che Ice­berg zu einem wich­ti­gen Daten­for­mat für daten­ge­trie­bene Orga­ni­sa­tio­nen. Es ermög­licht, das volle Poten­zial eines Data Lakes aus­schöp­fen zu kön­nen und gleich­zei­tig nicht auf die Vor­teile tra­di­tio­nel­ler DWH-Lösun­gen ver­zich­ten zu müssen.

Erfah­ren Sie hier mehr über Lösun­gen im Bereich Data Manage­ment oder besu­chen Sie eines unse­rer kos­ten­lo­sen Web­i­nare.