Cache DataFrames op serverless compute

Important

Deze functie bevindt zich in openbare preview-versie. Workspace-beheerders kunnen de toegang tot DataFrame-caching op serverless compute vanaf de Previews-pagina controleren. Zie Azure Databricks previews beheren.

Op serverless compute kun je een DataFrame cachen met df.cache() of df.persist() om een duur resultaat in je sessie te hergebruiken. Azure Databricks berekent de DataFrame wanneer je cache() aanroept en materialiseert het resultaat als een snapshot. De DataFrame en de DataFrames die je ervan bouwt, lezen vervolgens de snapshot voor de rest van je sessie in plaats van deze opnieuw te berekenen.

Requirements

  • De DataFrame-caching in serverless compute preview is ingeschakeld voor je werkruimte (standaard ingeschakeld). Workspace-beheerders kunnen het uitschakelen via de Previews-pagina. De preview is niet beschikbaar in werkruimtes met het compliance-beveiligingsprofiel ingeschakeld. Zie Previews op werkruimteniveau beheren.
  • Notebooks en taken op serverless compute moeten gebruik maken van omgevingsversie 5 of hoger.
  • Databricks Connect voor Python moet 18.1.8 of hoger zijn, en Databricks Connect voor Scala moet 18.1.5 of hoger zijn.

Oudere klanten krijgen de CACHE_REQUIRES_NEWER_CLIENT_ON_SERVERLESS_GC foutmelding.

Wanneer DataFrame-caching te gebruiken op serverless compute

Cache een DataFrame op serverless compute wanneer je dat nodig hebt:

  • Hergebruik het resultaat van een dure join, aggregatie of filter meerdere keren in dezelfde sessie.
  • Bereken één keer een streaming microbatch in een foreachBatch functie en schrijf deze vervolgens naar meerdere sinks.
  • Train meerdere machinelearningmodellen of stem ze af op dezelfde voorbereide featuregegevens.
  • Houd een stabiele snapshot bij terwijl je verschillende stappen van een analyse uitvoert, zelfs als de brontabellen veranderen.

Zie Best practices.

Cache DataFrame-API's op serverloze compute

Het volgende voorbeeld cachet één dag aan bestellingen gekoppeld aan klantgegevens, berekent de totale omzet van de dag, voegt de omzet per regio toe aan een rapporttabel en geeft vervolgens de cache vrij. Beide resultaten lezen de gecachte snapshot in plaats van de join opnieuw uit te voeren.

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 de volgende API-beschrijvingen df staat voor elke DataFrame in je sessie, zoals oct_15_orders in het voorgaande voorbeeld.

df.cache()

Het berekent df direct en cachet het resultaat als een snapshot voor de rest van je sessie.

  • Resultaat: Dezelfde gecachte DataFrame, df, nu gebaseerd op de snapshot in plaats van de berekening op de brontabellen. Zie het volgende gedrag.
  • Gedrag:
    • Voert de query van de DataFrame direct uit en materialiseert het resultaat als een snapshot voordat de oproep terugkeert.
    • Na de aanroep zijn df en het teruggegeven DataFrame (df zelf) gebaseerd op de snapshot. Ze zijn niet langer verbonden met de berekening op de brontabellen, dus lezen ze de snapshot in plaats van de query opnieuw te berekenen.
    • DataFrames die rechtstreeks of via andere afgeleide DataFrames zijn afgeleid van df, lezen de snapshot automatisch in plaats van de oorspronkelijke query opnieuw uit te voeren. Zie Lees de snapshot.
    • De snapshot is lokaal voor je sessie. Alleen de sessie die df in de cache heeft opgeslagen, kan het lezen. Zie Isolatie en privileges.
    • De snapshot duurt tot de sessie eindigt, hooguit zeven dagen. Azure Databricks maakt vervolgens automatisch zijn opslagruimte op de achtergrond vrij. Aanroepen van df.unpersist() maakt het mogelijk de opslag eerder vrij te maken. Zie Levenscyclus en tijdslimieten en Opslag en opschonen.
    • Als de berekening df faalt, df.cache() veroorzaakt de fout en df wordt niet gecachet.
    • Het aanroepen van df.cache() op een DataFrame die al gecached is, doet niets. df wordt niet opnieuw berekend.

De snapshot wordt vastgesteld nadat je df.cache() aanroept. Gegevens die daarna naar de tabellen worden geschreven waar df uit leest, en schemawijzigingen in die tabellen zoals toegevoegde of hernoemde kolommen, hebben daar geen invloed op. Om opnieuw te berekenen vanaf de nieuwste data, bouw je de DataFrame opnieuw op uit de brontabellen en cache je de nieuwe DataFrame indien nodig.

Lees de snapshot

Bij serverless compute is cachematching gebaseerd op DataFrame-afleiding. Na df.cache(), lezen alleen de volgende DataFrames de snapshot automatisch in plaats van de query op de brontabellen opnieuw te berekenen:

  • Het DataFrame dat je hebt gecachet, df.
  • Dataframes afgeleid van df, bijvoorbeeld met select(), filter(), , groupBy(), of join().
  • DataFrames zijn verder verketend vanuit die afgeleide DataFrames.

Een nieuw DataFrame dat dezelfde query herhaalt, leest de brontabellen, ook al is de logica identiek, omdat het niet is afgeleid van df.

Dit maakt cachematching expliciet en onder jouw controle: een DataFrame leest gecachte data alleen wanneer je deze afleidt van een gecachte DataFrame. Alle andere DataFrames lezen de brontabellen.

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")

Omdat df de snapshot leest in plaats van de DataFrames waaruit het is opgebouwd, kun je niet via die DataFrames naar de kolommen van df verwijzen. Zie Beperkingen.

df.persist(storageLevel)

Een alias van df.cache() die een opslagniveau accepteert.

  • Parameters:
    • storageLevel(optioneel): Een StorageLevel, zoals StorageLevel.DISK_ONLY. Serverless Compute accepteert elk opslagniveau en negeert het. De snapshot wordt op dezelfde manier opgeslagen voor elk opslagniveau en df.storageLevel geeft StorageLevel.DISK_ONLY.

De teruggevende waarde en het gedrag zijn hetzelfde als df.cache().

df.unpersist(blocking)

Geeft de gecachte snapshot van df vrij en vernietigt de DataFrame.

  • Parameters:
    • blocking (optioneel): Genegeerd. df.unpersist() geeft direct terug voor beide waarden.
  • Retourneert: Dezelfde DataFrame, df, nu vernietigd.
  • Gedrag:
    • Markeert de snapshot als klaar om te worden vrijgegeven. Azure Databricks verwijdert vervolgens de gecachte data en maakt op de achtergrond de opslag weer vrij.
    • Vernietigt df: df en alle DataFrames die daar eerder van zijn afgeleid, zijn niet langer bruikbaar, en elke volgende query daarop roept CACHE_DATAFRAME_ACCESS_AFTER_UNCACHE. Als je een DataFrame cachet die is afgeleid van df vóór je aanroept df.unpersist(), blijft dat DataFrame bruikbaar omdat het een eigen snapshot heeft.
    • Om met dezelfde databron te blijven werken, bouw je een nieuw DataFrame op basis van de oorspronkelijke databron, in plaats van het niet-gecachte DataFrame opnieuw te gebruiken.
    • Het aanroepen van df.unpersist() op een DataFrame die nooit is gecached, of die al is ontcached, is een no-op.

Roep df.unpersist() aan wanneer je de gecachte data niet meer nodig hebt, bijvoorbeeld wanneer geen latere stap in je notitieboek of taak deze leest. Dit stelt Azure Databricks in staat om de opslag eerder terug te winnen. Gebruik df.unpersist() niet om gegevens te vernieuwen. Om met de nieuwste data te werken, bouw je een nieuw DataFrame uit de brontabellen.

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

Hiermee haalt u het opslagniveau van df op.

  • Retourneert: StorageLevel.DISK_ONLY terwijl df is gecachet. StorageLevel.NONE voordat je het cachet en nadat je df.unpersist() aanroept.

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

Voor de methodesignaturen, zie de PySpark-referentie voor cache, persist, unpersist en storageLevel.

Levenscyclus- en tijdslimieten

Gecachte data bestaat alleen binnen de Azure Databricks-sessie waar je het cachet. Het wordt ontoegankelijk als de sessie eindigt en duurt maximaal zeven dagen. Na de zevendaagse limiet levert het gebruik van een gecachte DataFrame een foutmelding op in plaats van de brontabellen opnieuw te lezen. Om opnieuw te cachen, start je een nieuwe sessie.

Opslag en opruimen

Azure Databricks beheert automatisch de opslag voor gecachte data. Gecachte data wordt opgeslagen in cloudopslag, waarbij de specifieke opslaglocatie afhangt van het type werkruimte:

Nadat gecachete data ontoegankelijk wordt, maakt Azure Databricks automatisch de opslagruimte op de achtergrond weer vrij. Dit omvat gevallen waarin de sessie eindigt door een verbreking of een crash. Het aanroepen van df.unpersist() stelt Azure Databricks in staat om de opslag eerder terug te winnen.

Isolatie en bevoegdheden

Elke gebruiker die code kan draaien op serverless compute kan een DataFrame cachen. Je hebt geen extra privileges nodig.

Gecachte data biedt isolatie op sessieniveau. Alleen de sessie die een DataFrame heeft gecachet, kan de gecachte data lezen. Andere gebruikers kunnen er niet bij, waaronder andere gebruikers van dezelfde notebook.

De gecachte data bevat wat je mocht lezen toen je het cachede. Wijzigingen in machtigingen, rijfilters en kolommaskers die daarna op de brontabellen worden toegepast, zijn niet van toepassing op de gecachte data.

Aanbevolen procedures

  • Cache wanneer je een stabiele snapshot nodig hebt: Als je meerdere transformaties, aggregaties of drilldowns uitvoert op dezelfde berekende data, geeft de snapshot ze een consistente basislijn die niet verandert wanneer de brontabellen veranderen.
  • Cache dure berekeningen, geen gewone tabellezingen: df.cache() materialiseert het queryresultaat, en latere leesbewerkingen scannen die snapshot. Als je een uitlezing van een tabel cachet, zoals spark.table("main.sales.orders").cache(), scannen volgende uitlezingen nog steeds een volledige kopie van de tabel, dus caching bespaart weinig. Caching levert zijn vruchten af na duur werk zoals joins, aggregaties en complexe filters.
  • Cache geen data die je maar één keer leest: df.cache() berekent en slaat het resultaat direct op, wat tijd en opslag kost. Als je het resultaat maar één keer leest, is de initiële investering het niet waard.
  • Gebruik de cache door uit te gaan van de gecachte DataFrame: Om de snapshot te lezen, baseer je latere bewerkingen op de gecachte DataFrame-variabele, bijvoorbeeld df.select(...) of df.filter(...). Een onafhankelijk DataFrame dat op dezelfde berekening op de brontabellen is gebouwd, gebruikt de cache niet.
  • Gebruik geen cache voor cross-sessie- of cross-user datadeling: gecachete data is privé voor je sessie. Andere sessies, notitieboeken, jobruns en gebruikers kunnen het niet lezen. Om berekende resultaten te delen tussen sessies of met andere gebruikers, schrijf je ze naar een permanente tabel.
  • Houd sessies met gecachte data onder zeven dagen: Zie Levenscyclus en tijdslimieten. Als je workflow de data langer nodig heeft, schrijf het dan naar een tabel.
  • Roep df.unpersist() aan wanneer je de gecachte data niet meer nodig hebt: Dit stelt Azure Databricks in staat de opslagruimte eerder vrij te maken. Na de aanroep kunnen de DataFrame en de DataFrames die ervan zijn afgeleid niet worden gebruikt.
  • Gebruik df.unpersist() niet om gegevens te vernieuwen: df.unpersist() beëindigt de levensduur van de snapshot. Om wijzigingen in de brontabellen op te pikken, bouw je een nieuw DataFrame van de brontabellen.

Limitations

DataFrame-caching op serverless compute heeft de volgende beperkingen:

  • Kolomnamen en -typen: De volgende DataFrames kunnen niet worden gecached. Hernoem of cast de kolommen voordat je cachet, bijvoorbeeld met .alias("total_amount").
    • DataFrames met dubbele kolomnamen.
    • DataFrames met kolomnamen die spaties of een van de tekens ,;{}()= bevatten, zoals sum(amount) uit een aggregatie.
    • Dataframes met intervalkolommen.
    • DataFrames met arrays, maps of structs die waarden van het type NULL bevatten.
    • DataFrames zonder kolommen, of met alleen NULL-getypeerde kolommen.
  • Kolomreferenties: Nadat je een DataFrame hebt gecachet, kun je de kolommen niet meer refereren via de DataFrames waarop het is opgebouwd. Bijvoorbeeld, na oct_15_orders = orders.join(customers, "customer_id") en oct_15_orders.cache() verhoogt CANNOT_RESOLVE_DATAFRAME_COLUMNoct_15_orders.select(orders.amount). Gebruik oct_15_orders.amount of "amount" in plaats daarvan.
  • SQL- en catalogcache-API's: SQL-cache-instructies, zoals CACHE TABLE, en de tabelcachemethoden van spark.catalog worden niet ondersteund op serverless compute. Zie cachingbeperkingen. Om een queryresultaat in SQL opnieuw te gebruiken, gebruik je een sessie-lokale tijdelijke tabel.
  • Informatieschemaquery's: Wanneer veel sessies in een metastore DataFrames cachen, kunnen query's op information_schema.volumes en information_schema.schemata traag zijn of een time-out geven. Het filteren van volumes op catalogus maakt de query niet sneller. Query's op information_schema.tables worden niet beïnvloed.
  • Azure Government-regio's: DataFrame-caching wordt niet ondersteund op serverless computing in Azure Government-regio's.

Migreren van klassieke compute

Voor de meeste workloads geeft caching op serverless compute dezelfde resultaten als op klassieke compute, en draait bestaande code zonder wijzigingen. De volgende tabel geeft de verschillen weer.

Behavior Serverloze rekenkracht Klassieke rekenkracht
Cache matching Alleen de gecachte DataFrame en de DataFrames die ervan afgeleid zijn, gebruiken automatisch de cache. Elke query met dezelfde vorm van het uitvoeringsplan gebruikt automatisch de cache.
Versheid van gegevens Een consistente snapshot genomen op het moment dat je df.cache() aanroept. Varieert: gecachte data wordt in bepaalde gevallen ververst en in andere gevallen wordt een snapshot weergegeven.
Deelbereik Privé voor je sessie. Gedeeld over sessies binnen het cluster.
Materialisatie Eager: direct berekend wanneer je df.cache() aanroept. Lazy: berekend bij de eerste actie op de DataFrame.
df.unpersist() Vernietigt het DataFrame en geeft zijn snapshot deterministisch vrij. Geeft de cache in het geheugen vrij. Later gebruik van de DataFrame kan de nieuwste of verouderde data opleveren, afhankelijk van het product en de gegevensbron.

Het volgende beschrijft de eerste twee verschillen in meer detail:

  • Cacheovereenkomst:
    • Workloads die door de verandering worden beïnvloed: De meeste workloads zijn niet beïnvloed. Als je de gecachte DataFrame-variabele blijft gebruiken, bijvoorbeeld met df.select(...) of df.filter(...), werkt de cache zoals voorheen. De wijziging treft alleen workloads waarbij een onafhankelijk gebouwde DataFrame- of SQL-query de cache hergebruikt omdat deze dezelfde planvorm heeft. Op serverless compute lezen die queries de brontabellen.
    • Als je workload wordt beïnvloed: Gebruik de gecachte DataFrame-variabele waar je het gecachte resultaat nodig hebt, in plaats van dezelfde query opnieuw te bouwen.
  • Actualiteit van gegevens:
    • Werklasten die door de wijziging worden getroffen: De meeste workloads worden niet beïnvloed, omdat het opnieuw lezen van gecachte data na het schrijven naar de brontabellen ongebruikelijk is. De wijziging treft alleen workloads die naar de brontabellen schrijven en vervolgens verwachten dat de gecachte DataFrame de nieuwe data toont.
    • Als je werklast wordt beïnvloed: nadat je naar de brontabellen hebt geschreven, bouw dan een nieuw DataFrame op basis daarvan in plaats van de gecachte te hergebruiken.

Aanvullende bronnen