Was macht Iceberg-Tabellen erstellen?
Wann verwenden
- Erstellen oder Verwalten von Apache Iceberg-Tabellen auf einem Lakehouse.
- Auswahl der Partitionierung oder Entwicklung der Partitionierung / des Schemas ohne Neuschreibung.
- Verwalten von Snapshots, Zeitreisen, Kompaktierung und kleinen Dateien.
- NICHT verwenden für Delta-spezifische Arbeiten (dafür
engineering-databricks-pipelinesnutzen).
Arbeitsablauf
- [ ] Partitionierung nach Abfrage-Filterspalten; versteckte Partitionstransformationen verwenden
- [ ] MERGE für idempotente Upserts verwenden
- [ ] Kompaktierung (rewrite_data_files) planen, um kleine Dateien zu beheben
- [ ] Alte Snapshots ablaufen lassen + verwaiste Dateien entfernen, um Metadaten/Speicher zu kontrollieren
- [ ] Partitionierung / Schema nach Feld-ID entwickeln (keine Datenneuschreibung)
- Partitionierung auf Filterspalten mittels versteckter Partitionstransformationen (
days(ts),bucket(N, id)), sodass Abfragen bereinigen, ohne dass Benutzer abgeleitete Partitionsspalten hinzufügen müssen. - Idempotente Schreibvorgänge via
MERGE INTOmit dem Geschäftsschlüssel. - Regelmäßig kompaktieren – Streaming-/Kleinstbatch-Schreibvorgänge erzeugen viele kleine Dateien;
rewrite_data_filesstellt die Leseleistung wieder her. - Metadaten pflegen – alte Snapshots ablaufen lassen und verwaiste Dateien entfernen, sonst wachsen Snapshot-Verlauf und Speicher unbegrenzt.
- Frei entwickeln – Iceberg verfolgt Spalten/Partitionen per ID, sodass Hinzufügen/Löschen/Umbenennen und sogar Partitionsspezifikationsänderungen keine Datenneuschreibung erfordern.
Muster
Erstellen mit versteckter Partitionierung + MERGE-Upsert:
CREATE TABLE lake.db.orders (order_id BIGINT, customer_id BIGINT, amount DECIMAL, ordered_at TIMESTAMP)
USING iceberg PARTITIONED BY (days(ordered_at));
MERGE INTO lake.db.orders t USING staging s ON t.order_id = s.order_id
WHEN MATCHED THEN UPDATE SET *
WHEN NOT MATCHED THEN INSERT *;
Wartung (Spark-Prozeduren):
CALL lake.system.rewrite_data_files('db.orders'); -- kleine Dateien kompaktieren
CALL lake.system.expire_snapshots('db.orders', TIMESTAMP '2026-08-01 00:00:00');
CALL lake.system.remove_orphan_files(table => 'db.orders');
Zeitreisen – einen früheren Snapshot für Audit oder Wiederherstellung lesen:
SELECT * FROM lake.db.orders VERSION AS OF <snapshot_id>.
Partitionsentwicklung – ALTER TABLE ... ADD PARTITION FIELD bucket(16, customer_id) gilt nur für neue Daten; alte Daten bleiben gültig.
Häufige Fallstricke
- Keine Kompaktierung bei Streaming-Tabellen – Explosion kleiner Dateien senkt die Lesegeschwindigkeit drastisch.
- Snapshots nie ablaufen lassen – Metadaten und Speicher wachsen unbegrenzt; planen Sie das Ablaufen innerhalb Ihrer Zeitreise-Aufbewahrungsfrist.
- Übermäßige Partitionierung (z. B. stündlich bei geringem Volumen) – zu viele winzige Partitionen; Granularität an die Datenmenge anpassen.
- Explizite abgeleitete Partitionsspalten hinzufügen – hebelt den Sinn der versteckten Partitionierung aus; Transformationen verwenden.
- Blindes Überschreiben statt MERGE – verliert Idempotenz; MERGE nach Schlüssel.
- Verwaiste Dateien mit zu kurzem Zeitfenster entfernen – kann Dateien löschen, die von aktiven Schreibern noch benötigt werden; einen sicheren Grenzwert verwenden.