DataFrames auf serverlosen Rechenressourcen zwischenspeichern

Important

Dieses Feature befindet sich in der Public Preview. Arbeitsbereichsadministratoren können den Zugriff auf DataFrame-Zwischenspeicherung auf serverlosem Compute über die Seite Vorschauen steuern. Siehe Manage Azure Databricks Previews.

Bei serverless Computing kannst du einen DataFrame mit df.cache() oder df.persist() zur Wiederverwendung eines teuren Ergebnisses in deiner Sitzung cachen. Azure Databricks berechnet den DataFrame, wenn Sie cache() aufrufen, und materialisiert das Ergebnis als Snapshot. Der DataFrame und die DataFrames, die du daraus aufbaust, lesen dann den Snapshot für den Rest deiner Sitzung, anstatt ihn neu zu berechnen.

Requirements

  • Die Vorschau für DataFrame-Caching auf serverlosem Compute ist für deinen Arbeitsbereich aktiviert (standardmäßig aktiviert). Workspace-Administratoren können es über die Previews-Seite deaktivieren. Die Vorschau ist in Arbeitsbereichen mit aktiviertem Compliance-Sicherheitsprofil nicht verfügbar. Siehe Verwalten von Vorschauen auf Arbeitsbereichsebene.
  • Notebooks und Jobs auf serverlosem Computing müssen Umgebungsversion 5 oder höher verwenden.
  • Databricks Connect für Python muss 18.1.8 oder höher sein, und Databricks Connect für Scala muss 18.1.5 oder höher sein.

Ältere Clients erhalten den Fehler CACHE_REQUIRES_NEWER_CLIENT_ON_SERVERLESS_GC.

Wann sollte man DataFrame-Caching auf serverlosem Compute verwenden

Cachen Sie einen DataFrame auf serverless Compute, wenn Sie Folgendes benötigen:

  • Verwenden Sie das Ergebnis eines teuren Joins, Aggregations oder Filters mehrmals in derselben Sitzung.
  • Berechnen Sie einen Streaming-Mikro-Batch einmal in einer foreachBatch Funktion und schreiben Sie ihn dann in mehrere Sinks.
  • Trainieren oder optimieren Sie mehrere Machine Learning-Modelle mit denselben vorbereiteten Featuredaten.
  • Behalten Sie während mehrerer Schritte einer Analyse eine stabile Momentaufnahme bei, auch wenn sich die Quelltabellen ändern.

Weitere Informationen finden Sie unter "Bewährte Methoden".

DataFrame-APIs auf serverlosem Compute zwischenspeichern

Das folgende Beispiel speichert einen Tag von Bestellungen, die mit Kundendaten verbunden sind, berechnet den Gesamtumsatz des Tages, fügt den Umsatz nach Region einer Berichtstabelle hinzu und gibt dann den Cache frei. Beide Ergebnisse lesen den zwischengespeicherten Snapshot, anstatt den Join erneut auszuführen.

Python

from pyspark.sql import functions as F

# The DataFrame to cache: one day of orders joined with customer data.
oct_15_orders = (
    spark.table("main.sales.orders")
    .filter(F.col("order_date") == "2026-10-15")
    .join(spark.table("main.sales.customers"), "customer_id")
)
oct_15_orders.cache()

# Both results are built from oct_15_orders, so they read the cached snapshot.
total_revenue = oct_15_orders.agg(F.sum("amount")).first()[0]
print(f"Total revenue on 2026-10-15: {total_revenue}")

revenue_by_region = oct_15_orders.groupBy("order_date", "region").agg(F.sum("amount").alias("revenue"))
revenue_by_region.write.mode("append").saveAsTable("main.reports.revenue_by_region")

# Release the cache and the DataFrame when you no longer need it.
# oct_15_orders and DataFrames built from it can no longer be used.
oct_15_orders.unpersist()

Scala

import org.apache.spark.sql.functions._

// The DataFrame to cache: one day of orders joined with customer data.
val oct15Orders = spark.table("main.sales.orders")
  .filter(col("order_date") === "2026-10-15")
  .join(spark.table("main.sales.customers"), "customer_id")
oct15Orders.cache()

// Both results are built from oct15Orders, so they read the cached snapshot.
val totalRevenue = oct15Orders.agg(sum("amount")).first().get(0)
println(s"Total revenue on 2026-10-15: $totalRevenue")

val revenueByRegion = oct15Orders.groupBy("order_date", "region").agg(sum("amount").alias("revenue"))
revenueByRegion.write.mode("append").saveAsTable("main.reports.revenue_by_region")

// Release the cache and the DataFrame when you no longer need it.
// oct15Orders and DataFrames built from it can no longer be used.
oct15Orders.unpersist()

In den folgenden API-Beschreibungen df steht für jeden DataFrame in Ihrer Sitzung, wie oct_15_orders im vorherigen Beispiel.

df.cache()

Berechnet df sofort und speichert das Ergebnis als Snapshot für den Rest deiner Sitzung.

  • Gibt zurück: Denselben zwischengespeicherten DataFrame, df, der jetzt auf der Momentaufnahme anstelle der Berechnung für seine Quelltabellen basiert. Sieh dir folgendes Verhalten an.
  • Verhalten:
    • Führt die Abfrage des DataFrame sofort aus und materialisiert das Ergebnis als Snapshot, bevor der Aufruf zurückkehrt.
    • Nach dem Aufruf basieren df und der zurückgegebene DataFrame (df selbst) auf der Momentaufnahme. Sie sind nicht mehr mit der Berechnung in den Quelltabellen verbunden, daher lesen sie den Schnappschuss, anstatt die Abfrage neu zu berechnen.
    • DataFrames, abgeleitet von df, direkt oder über andere abgeleitete DataFrames, lesen den Schnappschuss automatisch, anstatt die ursprüngliche Abfrage erneut auszuführen. Siehe Snapshot lesen.
    • Die Momentaufnahme ist lokal für Ihre Sitzung. Nur die Sitzung, die df zwischengespeichert hat, kann es lesen. Siehe Isolation und Privilegien.
    • Der Snapshot dauert bis zum Ende der Sitzung, höchstens sieben Tage. Azure Databricks gibt dann seinen Speicherplatz im Hintergrund automatisch wieder frei. Durch den Aufruf von df.unpersist() kann der Speicher früher freigegeben werden. Siehe Lebenszyklus und Zeitlimits sowie Speicherung und Bereinigung.
    • Wenn die Berechnung von df fehlschlägt, löst df.cache() den Fehler aus, und df wird nicht zwischengespeichert.
    • Das Aufrufen df.cache() eines bereits zwischengespeicherten DataFrames bewirkt nichts. df wird nicht wieder berechnet.

Die Momentaufnahme ist nach dem Aufruf von df.cache() fixiert. Daten, die danach in die Tabellen geschrieben werden, aus denen df liest, und Schemaänderungen an diesen Tabellen, wie hinzugefügte oder umbenannte Spalten, haben darauf keinen Einfluss. Um aus den neuesten Daten neu zu berechnen, baue den DataFrame erneut aus den Quelltabellen und cache den neuen DataFrame, falls nötig.

Lies den Snapshot

Bei serverlosem Computing basiert das Cache-Matching auf der DataFrame-Herleitung. Nach df.cache() lesen nur die folgenden DataFrames den Snapshot automatisch, anstatt die Abfrage in den Quelltabellen neu zu berechnen:

  • Der DataFrame, den du zwischengespeichert hast, df.
  • Datenframes, abgeleitet von df, zum Beispiel mit select(), filter(), , groupBy()oder join().
  • DataFrames, die aus diesen abgeleiteten DataFrames weiter verkettet sind.

Ein neuer DataFrame, der dieselbe Abfrage wiederholt, liest die Quelltabellen, obwohl seine Logik identisch ist, da er nicht von df abgeleitet ist.

Dadurch wird das Cache-Matching explizit und unter deine Kontrolle gestellt: Ein DataFrame liest zwischengespeicherte Daten nur, wenn du sie von einem gecachten DataFrame ableitest. Jeder andere DataFrame liest die Quelltabellen.

Python

oct_15_orders = (
    spark.table("main.sales.orders")
    .filter(F.col("order_date") == "2026-10-15")
    .join(spark.table("main.sales.customers"), "customer_id")
)
# The join runs one time, when you call cache().
oct_15_orders.cache()

# Derived from oct_15_orders: read the snapshot, so the join doesn't run again.
large_orders = oct_15_orders.filter(F.col("amount") > 1000)
revenue_by_region = oct_15_orders.groupBy("order_date", "region").agg(F.sum("amount").alias("revenue"))

# Derived from large_orders, which is derived from oct_15_orders: also reads the snapshot.
large_orders_by_region = large_orders.groupBy("region").count()

# Not derived from oct_15_orders: reads the source tables and runs the join again.
same_query = (
    spark.table("main.sales.orders")
    .filter(F.col("order_date") == "2026-10-15")
    .join(spark.table("main.sales.customers"), "customer_id")
)

Scala

val oct15Orders = spark.table("main.sales.orders")
  .filter(col("order_date") === "2026-10-15")
  .join(spark.table("main.sales.customers"), "customer_id")
// The join runs one time, when you call cache().
oct15Orders.cache()

// Derived from oct15Orders: read the snapshot, so the join doesn't run again.
val largeOrders = oct15Orders.filter(col("amount") > 1000)
val revenueByRegion = oct15Orders.groupBy("order_date", "region").agg(sum("amount").alias("revenue"))

// Derived from largeOrders, which is derived from oct15Orders: also reads the snapshot.
val largeOrdersByRegion = largeOrders.groupBy("region").count()

// Not derived from oct15Orders: reads the source tables and runs the join again.
val sameQuery = spark.table("main.sales.orders")
  .filter(col("order_date") === "2026-10-15")
  .join(spark.table("main.sales.customers"), "customer_id")

Da df den Snapshot statt der DataFrames liest, aus denen er erstellt wurde, kann man die Spalten von df nicht über diese DataFrames referenzieren. Informationen finden Sie unter Einschränkungen.

df.persist(storageLevel)

Ein Alias von df.cache(), der eine Speicherebene akzeptiert.

  • Parameter:
    • storageLevel (optional): Ein StorageLevel, wie zum Beispiel StorageLevel.DISK_ONLY. Serverloses Compute akzeptiert jede Speicherebene und ignoriert sie. Der Schnappschuss wird für jede Speicherebene auf die gleiche Weise gespeichert, und df.storageLevel gibt StorageLevel.DISK_ONLY zurück.

Der Rückgabewert und das Verhalten sind identisch mit df.cache().

df.unpersist(blocking)

Gibt den zwischengespeicherten Snapshot frei df und zerstört den DataFrame.

  • Parameter:
    • blocking (optional): Ignoriert. df.unpersist() gibt für beide Werte sofort etwas zurück.
  • Gibt zurück: Denselben DataFrame, df, der jetzt zerstört ist.
  • Verhalten:
    • Markiert die Momentaufnahme als bereit zur Freigabe. Azure Databricks löscht dann die zwischengespeicherten Daten und gibt den Speicherplatz im Hintergrund wieder frei.
    • Zerstört df: df und alle zuvor daraus abgeleiteten DataFrames sind nicht mehr nutzbar, und jede nachfolgende Abfrage darauf wirft CACHE_DATAFRAME_ACCESS_AFTER_UNCACHE. Wenn du einen DataFrame cachest, der von df vor dem Aufruf df.unpersist()abgeleitet ist, bleibt dieser DataFrame nutzbar, weil er einen eigenen Snapshot hat.
    • Um weiterhin mit derselben Datenquelle zu arbeiten, erstellen Sie einen neuen DataFrame aus der ursprünglichen Datenquelle, anstatt den nicht zwischengespeicherten DataFrame wiederzuverwenden.
    • Der Aufruf von df.unpersist() bei einem DataFrame, der nie zwischengespeichert wurde oder bereits aus dem Cache entfernt wurde, ist ein No-Op.

Rufe df.unpersist() auf, wenn du die zwischengespeicherten Daten nicht mehr brauchst, zum Beispiel wenn kein späterer Schritt in deinem Notizbuch oder Job sie liest. Dies ermöglicht es Azure Databricks, den Speicher früher zurückzugewinnen. Nutze df.unpersist() nicht, um Daten zu aktualisieren. Um mit den neuesten Daten zu arbeiten, erstellen Sie einen neuen DataFrame aus den Quelltabellen.

Python

oct_15_orders = spark.table("main.sales.orders").filter(F.col("order_date") == "2026-10-15")
oct_15_orders.cache()
large_orders = oct_15_orders.filter(F.col("amount") > 1000)
orders_per_customer = oct_15_orders.groupBy("customer_id").count()
orders_per_customer.cache()  # Has its own snapshot.

# Acknowledge that the cached data is no longer needed.
# This releases the storage and destroys oct_15_orders.
oct_15_orders.unpersist()

oct_15_orders.count()  # Raises CACHE_DATAFRAME_ACCESS_AFTER_UNCACHE.
large_orders.count()  # Raises CACHE_DATAFRAME_ACCESS_AFTER_UNCACHE.
orders_per_customer.count()  # Reads its own snapshot.

# If you need the data again later, build a new DataFrame from the source tables.
oct_15_orders = spark.table("main.sales.orders").filter(F.col("order_date") == "2026-10-15")

Scala

var oct15Orders = spark.table("main.sales.orders").filter(col("order_date") === "2026-10-15")
oct15Orders.cache()
val largeOrders = oct15Orders.filter(col("amount") > 1000)
val ordersPerCustomer = oct15Orders.groupBy("customer_id").count()
ordersPerCustomer.cache() // Has its own snapshot.

// Acknowledge that the cached data is no longer needed.
// This releases the storage and destroys oct15Orders.
oct15Orders.unpersist()

oct15Orders.count() // Throws CACHE_DATAFRAME_ACCESS_AFTER_UNCACHE.
largeOrders.count() // Throws CACHE_DATAFRAME_ACCESS_AFTER_UNCACHE.
ordersPerCustomer.count() // Reads its own snapshot.

// If you need the data again later, build a new DataFrame from the source tables.
oct15Orders = spark.table("main.sales.orders").filter(col("order_date") === "2026-10-15")

df.storageLevel

Ruft die Speicherebene von df ab.

  • Gibt zurück: StorageLevel.DISK_ONLY, während df zwischengespeichert wird. StorageLevel.NONE bevor du es zwischenspeicherst und nachdem du df.unpersist() aufgerufen hast.

Python

from pyspark import StorageLevel

oct_15_orders.cache()
oct_15_orders.storageLevel == StorageLevel.DISK_ONLY  # True

Scala

import org.apache.spark.storage.StorageLevel

oct15Orders.cache()
oct15Orders.storageLevel == StorageLevel.DISK_ONLY // true

Für die Methodensignaturen siehe die PySpark-Referenz für cache, persist, unpersist und storageLevel.

Lebenszyklus- und Zeitlimits

Zwischengespeicherte Daten existieren nur in der Azure Databricks-Sitzung, in der du sie cachest. Sie wird nach Ende der Sitzung unzugänglich und ist höchstens sieben Tage gültig. Nach dem Sieben-Tage-Limit führt die Verwendung eines zwischengespeicherten DataFrames zu einem Fehler, anstatt die Quelltabellen erneut zu lesen. Um erneut zu cachen, starte eine neue Sitzung.

Speicher und Bereinigung

Azure Databricks verwaltet automatisch den Speicher für zwischengespeicherte Daten. Zwischengespeicherte Daten werden in Cloud-Speicher gespeichert, wobei der genaue Speicherort vom Typ Ihres Arbeitsbereichs abhängt:

Nachdem zwischengespeicherte Daten nicht mehr zugänglich sind, gibt Azure Databricks den Speicher im Hintergrund automatisch wieder frei. Dazu gehören auch Fälle, in denen die Sitzung durch eine Verbindungsunterbrechung oder einen Absturz endet. Der Aufruf von df.unpersist() ermöglicht es Azure Databricks, den Speicher früher freizugeben.

Isolation und Berechtigungen

Jeder Nutzer, der Code in einer serverlosen Rechenumgebung ausführen kann, kann einen DataFrame cachen. Du brauchst keine zusätzlichen Privilegien.

Zwischengespeicherte Daten bieten eine Isolation auf Sitzungsebene. Nur die Sitzung, die einen DataFrame zwischengespeichert hat, kann seine zwischengespeicherten Daten lesen. Andere Benutzer können nicht darauf zugreifen, einschließlich anderer Benutzer desselben Notebooks.

Die zwischengespeicherten Daten enthalten das, was du lesen durftest, als du sie zwischengespeichert hast. Berechtigungsänderungen, Zeilenfilter und Spaltenmasken, die anschließend auf die Quelltabellen angewendet werden, gelten nicht für die zwischengespeicherten Daten.

Optimale Verfahren

  • Cache, wenn du einen stabilen Snapshot brauchst: Wenn du mehrere Transformationen, Aggregationen oder Drilldowns auf denselben berechneten Daten ausführst, liefert der Snapshot ihnen eine konsistente Basislinie, die sich nicht ändert, wenn sich die Quelltabellen ändern.
  • Aufwendige Berechnungen cachen, nicht einfache Tabellenlesevorgänge: df.cache() materialisiert das Abfrageergebnis und spätere Lesevorgänge scannen diesen Snapshot. Wenn du einen einfachen Lesevorgang einer Tabelle zwischenspeicherst, wie z. B. spark.table("main.sales.orders").cache(), scannen spätere Lesevorgänge trotzdem eine vollständige Kopie der Tabelle, sodass Caching wenig spart. Caching zahlt sich nach teuren Arbeiten wie Joins, Aggregationen und komplexen Filtern aus.
  • Daten, die Sie nur einmal lesen, nicht zwischenspeichern: df.cache() berechnet und speichert das Ergebnis sofort, was Zeit und Speicherplatz beansprucht. Wenn Sie das Ergebnis nur einmal lesen, lohnen sich die Anschaffkosten nicht.
  • Verwenden Sie den Cache, indem Sie auf dem zwischengespeicherten DataFrame aufbauen: Um den Schnappschuss zu lesen, bauen Sie spätere Operationen auf der zwischengespeicherten DataFrame-Variablen auf, zum Beispiel df.select(...) oder df.filter(...). Ein unabhängiger DataFrame, der aus derselben Berechnung auf den Quelltabellen gebaut ist, verwendet den Cache nicht.
  • Verwenden Sie keinen Cache für den Cross-Session- oder Cross-User-Datenaustausch: Zwischengespeicherte Daten sind privat für Ihre Sitzung. Andere Sitzungen, Notizbücher, Job-Runs, und Nutzer können es nicht lesen. Um berechnete Ergebnisse über Sitzungen hinweg oder mit anderen Nutzern zu teilen, schreiben Sie sie in eine permanente Tabelle.
  • Sitzungen mit zwischengespeicherten Daten nicht länger als sieben Tage beibehalten: Siehe Lebenszyklus und Zeitlimits. Wenn dein Workflow die Daten länger benötigt, schreibe sie in eine Tabelle.
  • Rufen Sie df.unpersist() auf, wenn Sie die zwischengespeicherten Daten nicht mehr benötigen: Dies ermöglicht es Azure Databricks, den Speicher früher freizugeben. Nach dem Aufruf können der DataFrame und die daraus abgeleiteten DataFrames nicht mehr verwendet werden.
  • df.unpersist() nicht zum Aktualisieren von Daten verwenden: df.unpersist() beendet die Lebensdauer der Momentaufnahme. Um Änderungen in den Quelltabellen zu erkennen, erstellen Sie einen neuen DataFrame aus den Quelltabellen.

Einschränkungen

DataFrame-Caching auf serverloser Rechenleistung hat folgende Einschränkungen:

  • Spaltennamen und -typen: Die folgenden DataFrames können nicht zwischengespeichert werden. Umbenennen oder casten Sie die Spalten, bevor Sie cachen, zum Beispiel mit .alias("total_amount").
    • DataFrames mit doppelten Spaltennamen.
    • DataFrames mit Spaltennamen, die Leerzeichen oder eines der Zeichen ,;{}()= enthalten, z. B. sum(amount) aus einer Aggregation.
    • DataFrames mit Intervallspalten.
    • DataFrames mit Arrays, Maps oder Structs, die NULL-typierte Werte enthalten.
    • DataFrames ohne Spalten oder nur mit NULL-typierten Spalten.
  • Spaltenreferenzen: Nachdem du einen DataFrame zwischengespeichert hast, kannst du seine Spalten nicht mehr über die DataFrames, aus denen er gebaut wurde, referenzieren. Zum Beispiel erhöht oct_15_orders.cache() nach CANNOT_RESOLVE_DATAFRAME_COLUMN und oct_15_orders = orders.join(customers, "customer_id")oct_15_orders.select(orders.amount). Verwenden Sie stattdessen oct_15_orders.amount oder "amount".
  • SQL- und Katalogcache-APIs: SQL-Cache-Anweisungen wie CACHE TABLE und die Tabellencache-Methoden von spark.catalog werden bei serverloser Berechnung nicht unterstützt. Siehe Caching-Einschränkungen. Um ein Abfrageergebnis in SQL wiederzuverwenden, verwenden Sie eine session-lokale temporäre Tabelle.
  • Informationsschemaabfragen: Wenn viele Sitzungen in einem Metastore DataFrames zwischenspeichern, können Abfragen für information_schema.volumes und information_schema.schemata langsam sein oder ein Timeout aufweisen. Das Filtern von volumes nach Katalog macht die Abfrage nicht schneller. Abfragen auf information_schema.tables sind nicht betroffen.
  • Azure Government-Regionen: DataFrame-Caching wird in Azure Government-Regionen auf serverlosem Compute nicht unterstützt.

Von klassischem Compute migrieren

Für die meisten Workloads liefert Caching auf serverless Compute die gleichen Ergebnisse wie bei klassischer Compute, und bestehender Code läuft ohne Änderungen. In der folgenden Tabelle sind die Unterschiede aufgeführt.

Behavior Serverloses Rechnen Klassisches Rechnen
Cache-Abgleich Nur der zwischengespeicherte DataFrame und die daraus abgeleiteten DataFrames verwenden den Cache automatisch. Jede Abfrage mit derselben Planstruktur verwendet automatisch den Cache.
Datenaktualität Eine konsistente Momentaufnahme, die zum Zeitpunkt des Aufrufs von df.cache() erstellt wurde. Variiert: Zwischengespeicherte Daten werden in bestimmten Fällen aktualisiert und dienen in anderen als Momentaufnahme.
Freigabebereich Privat für Ihre Sitzung. Geteilt über Sitzungen innerhalb des Clusters.
Materialisation Eager: sofort berechnet, wenn du df.cache() aufrufst. Lazy: bei der ersten Aktion auf dem DataFrame berechnet.
df.unpersist() Zerstört den DataFrame und gibt seinen Schnappschuss deterministisch frei. Gibt den In-Memory-Cache frei. Bei der späteren Verwendung des DataFrames werden je nach Produkt und Datenquelle möglicherweise die neuesten oder veraltete Daten abgerufen.

Im Folgenden werden die ersten beiden Unterschiede ausführlicher beschrieben:

  • Cache-Matching:
    • Workloads, die von der Änderung betroffen sind: Die meisten Workloads sind nicht betroffen. Wenn du weiterhin die zwischengespeicherte DataFrame-Variable verwendest, zum Beispiel mit df.select(...) oder df.filter(...), funktioniert der Cache wie zuvor. Die Änderung betrifft nur Workloads, bei denen ein unabhängig erstelltes DataFrame oder eine SQL-Abfrage den Cache wiederverwendet, weil dieselbe Planstruktur vorliegt. Bei serverlosem Computing lesen diese Abfragen die Quelltabellen.
    • Wenn Ihre Arbeitslast betroffen ist: Verwenden Sie die zwischengespeicherte DataFrame-Variable dort, wo Sie das zwischengespeicherte Ergebnis benötigen, anstatt dieselbe Abfrage erneut zu erstellen.
  • Datenaktualität:
    • Von der Änderung betroffene Workloads: Die meisten Workloads sind nicht betroffen, da das erneute Lesen von zwischengespeicherten Daten nach dem Schreiben in die Quelltabellen ungewöhnlich ist. Die Änderung betrifft nur Workloads, die in die Quelltabellen schreiben und dann erwarten, dass der zwischengespeicherte DataFrame die neuen Daten anzeigt.
    • Wenn deine Arbeitslast betroffen ist: Nachdem du in die Quelltabellen geschrieben hast, baue daraus einen neuen DataFrame, anstatt den zwischengespeicherten wiederzuverwenden.

Weitere Ressourcen