Remarque
L’accès à cette page requiert une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page requiert une autorisation. Vous pouvez essayer de modifier des répertoires.
Important
Cette fonctionnalité est disponible en préversion publique. Les administrateurs de l’espace de travail peuvent contrôler l’accès à la mise en cache de DataFrame sur le calcul sans serveur depuis la page des Previews. Consultez Gérer les préversions d’Azure Databricks.
En calcul serverless, vous pouvez mettre en cache un DataFrame avec df.cache() ou df.persist() pour réutiliser un résultat coûteux dans votre session. Azure Databricks calcule le DataFrame lorsque vous appelez cache() et matérialise le résultat sous forme d’instantané. Le DataFrame et les DataFrames que vous créez à partir de celui-ci utilisent ensuite cet instantané pendant le reste de votre session au lieu de le recalculer.
Requirements
- L’aperçu de la mise en cache des DataFrame sur le calcul sans serveur est activé pour votre espace de travail (activé par défaut). Les administrateurs de l’espace de travail peuvent le désactiver depuis la page Aperçus. L’aperçu n’est pas disponible dans les espaces de travail avec le profil de sécurité de conformité activé. Consultez Gérer les préversions au niveau de l’espace de travail.
- Les notebooks et les jobs sur le calcul serverless doivent utiliser la version d’environnement 5 ou supérieure.
- Databricks Connect pour Python doit être 18.1.8 ou supérieur, et Databricks Connect pour Scala doit être 18.1.5 ou plus.
Les clients plus âgés rencontrent l’erreur CACHE_REQUIRES_NEWER_CLIENT_ON_SERVERLESS_GC.
Quand utiliser la mise en cache de DataFrame avec le calcul serverless
Mettez en cache une DataFrame sur un calcul serverless lorsque vous avez besoin de :
- Réutilisez le résultat d’une jointure coûteuse, d’une agrégation ou d’un filtre plusieurs fois dans la même session.
- Calculez un micro-batch en streaming une fois dans une fonction
foreachBatch, puis écrivez-le dans plusieurs sorties. - Entraînez ou ajustez plusieurs modèles d’apprentissage automatique sur les mêmes données de fonctionnalités préparées.
- Conservez un instantané stable pendant que vous effectuez plusieurs étapes d’analyse, même si les tables sources changent.
Consultez les meilleures pratiques.
Mettre en cache les API DataFrame sur un calcul serverless
L’exemple suivant met en cache une journée de commandes jointes aux données clients, calcule le chiffre d’affaires total de la journée, ajoute les revenus par région à une table de rapport, puis libère la cache. Les deux résultats lisent l’instantané mis en cache au lieu de relancer la jointure.
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()
Dans les descriptions API suivantes, df désigne n’importe quel DataFrame dans votre session, comme oct_15_orders dans l’exemple précédent.
df.cache()
Il calcule df immédiatement et met en cache le résultat en instantané pour le reste de la session.
-
Retour : Le même DataFrame mis en cache,
df, désormais basé sur l’instantané au lieu du calcul sur ses tables sources. Voir le comportement suivant. -
Comportement:
- Lance immédiatement la requête du DataFrame et matérialise le résultat sous forme d’instantané avant le retour de l’appel.
- Après l’appel,
dfet la DataFrame retournée (dfelle-même) sont basés sur l’instantané. Ils ne sont plus connectés au calcul sur les tables sources, donc ils lisent l’instantané au lieu de recalculer la requête. - Les DataFrames dérivés de
df, directement ou via d’autres DataFrames dérivés, lisent automatiquement l’instantané au lieu d’exécuter à nouveau la requête originale. Voir Lire l’instantané. - L’instantané est propre à votre session. Seule la session qui a mis
dfen cache peut le lire. Voir Isolement et privilèges. - L’instantané dure jusqu’à la fin de la session, au maximum sept jours. Azure Databricks libère alors automatiquement l’espace de stockage en arrière-plan. Appeler
df.unpersist()lui permet de récupérer le stockage plus tôt. Voir Cycle de vie et limites de temps et Stockage et nettoyage. - Si le calcul
dféchoue,df.cache()génère l’erreur etdfn’est pas mise en cache. - Appeler
df.cache()sur un DataFrame déjà mis en cache ne fait rien.dfn’est pas calculé à nouveau.
L’instantané est figé après que vous avez appelé df.cache(). Les données écrites ensuite dans les tables dont df lit les données, ainsi que les modifications du schéma de ces tables, comme les colonnes ajoutées ou renommées, n’ont pas d’effet sur celui-ci. Pour recalculer à partir des données les plus récentes, reconstruisez le DataFrame à partir des tables sources, et mettez en cache le nouveau DataFrame si nécessaire.
Lisez la capture instantanée
En calcul serverless, l’appariement du cache est basé sur la dérivation de DataFrame. Après df.cache(), seules les DataFrames suivantes lisent automatiquement l’instantané au lieu de recalculer la requête sur les tables sources :
- Le DataFrame que vous avez mis en cache,
df. - DataFrames dérivés de
df, par exemple avecselect(),filter(),groupBy(), oujoin(). - DataFrames davantage enchaînés à partir de ces DataFrames dérivés.
Un nouveau DataFrame qui répète la même requête lit les tables sources, même si sa logique est identique, car il ne dérive pas de df.
Cela rend la correspondance de cache explicite et sous votre contrôle : un DataFrame ne lit les données mises en cache que lorsque vous les dérivez d’un DataFrame mis en cache. Un DataFrame sur deux lit les tables sources.
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")
Parce que df lit l’instantané au lieu des DataFrames à partir desquels il a été construit, vous ne pouvez pas référencer les colonnes de df via ces DataFrames. Consultez Limitations.
df.persist(storageLevel)
Un alias de df.cache() qui accepte un niveau de stockage.
-
Paramètres :
-
storageLevel(optionnel) : UnStorageLevel, commeStorageLevel.DISK_ONLY. Le calcul serverless accepte n’importe quel niveau de stockage et l’ignore. L’instantané est stocké de la même manière pour chaque niveau de stockage, etdf.storageLevelretourneStorageLevel.DISK_ONLY.
-
La valeur de retour et le comportement sont les mêmes que df.cache().
df.unpersist(blocking)
Libère l’instantané mis en cache de df et détruit le DataFrame.
-
Paramètres :
-
blocking(optionnel) : Ignoré.df.unpersist()renvoie immédiatement pour l’une ou l’autre valeur.
-
-
Renvoie : Le même DataFrame,
df, maintenant détruit. -
Comportement :
- Marque le snapshot comme prêt à être libéré. Azure Databricks supprime ensuite les données mises en cache et libère l’espace de stockage en arrière-plan.
- Détruit
df:dfet toutes les DataFrames précédemment dérivées de celui-ci ne sont plus utilisables, et toute requête ultérieure sur elles génèreCACHE_DATAFRAME_ACCESS_AFTER_UNCACHE. Si vous mettez en cache un DataFrame dérivé dedfavant d’appelerdf.unpersist(), ce DataFrame reste utilisable, car il possède son propre instantané. - Pour continuer à travailler avec la même source de données, construisez un nouveau DataFrame à partir de la source de données originale, au lieu de réutiliser le DataFrame non mis en cache.
- Appeler
df.unpersist()sur une DataFrame qui n’a jamais été mise en cache, ou qui a déjà été retirée du cache, est sans effet.
Appelez df.unpersist() lorsque vous n’avez plus besoin des données mises en cache, par exemple lorsqu’aucune étape ultérieure de votre notebook ou de votre job ne les lit. Cela permet à Azure Databricks de récupérer l’espace de stockage plus tôt. Ne pas utiliser df.unpersist() pour rafraîchir les données. Pour travailler avec les données les plus récentes, construisez un nouveau DataFrame à partir des tables sources.
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
Obtient le niveau de stockage de df.
-
Retour :
StorageLevel.DISK_ONLYpendant quedfest mis en cache.StorageLevel.NONEavant de le mettre en cache et après avoir appelédf.unpersist().
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
Pour les signatures de méthode, voir la référence PySpark pour cache, persist, unpersist et storageLevel.
Limites de cycle de vie et de temps
Les données mises en cache n’existent que dans la session Azure Databricks où vous les mettez en cache. Il devient inaccessible à la fin de la session, et il dure au maximum sept jours. Après la limite de sept jours, utiliser un DataFrame mis en cache génère une erreur au lieu de relire les tables sources. Pour mettre en cache à nouveau, lance une nouvelle session.
Stockage et nettoyage
Azure Databricks gère automatiquement le stockage des données mises en cache. Les données mises en cache sont stockées dans le cloud, l’emplacement spécifique de stockage dépendant du type d’espace de travail :
- Espaces de travail sans serveur : Les données mises en cache sont stockées dans le stockage par défaut. Si vous avez configuré une clé gérée par le client pour les services gérés, les données mises en cache utilisent cette clé. Référez-vous à la section Clés gérées par le client pour le chiffrement.
- Espaces de travail classiques : Les données mises en cache sont stockées dans le compte de stockage de l’espace de travail configuré au moment de la création de l’espace de travail. Vous pouvez configurer le chiffrement au niveau du compte de stockage.
Après que les données mises en cache deviennent inaccessibles, Azure Databricks libère automatiquement l’espace de stockage en arrière-plan. Cela inclut les cas où la session se termine à cause d’une déconnexion ou d’un plantage. L’appel df.unpersist() permet à Azure Databricks de récupérer le stockage plus tôt.
Isolation et privilèges
Tout utilisateur capable d’exécuter du code sur un calcul serverless peut mettre en cache un DataFrame. Tu n’as pas besoin de privilèges supplémentaires.
Les données mises en cache offrent une isolation au niveau de la session. Seule la session qui a mis en cache un DataFrame peut lire ses données mises en cache. Les autres utilisateurs ne peuvent pas y accéder, y compris les autres utilisateurs du même carnet.
Les données mises en cache contiennent ce que vous étiez autorisé à lire lorsque vous les avez mises en cache. Les modifications de permissions, les filtres de lignes et les masques de colonnes appliqués ensuite aux tables sources ne s’appliquent pas aux données mises en cache.
Bonnes pratiques
- Mettre en cache lorsque vous avez besoin d’un instantané stable : Si vous effectuez plusieurs transformations, agrégations ou découpages sur les mêmes données calculées, l’instantané leur fournit une base de référence cohérente qui ne change pas lorsque les tables sources changent.
-
Mettre en cache des calculs coûteux, pas des lectures de table simples :
df.cache()matérialise le résultat de la requête, puis les lectures ultérieures scannent ce snapshot. Si vous mettez en cache une lecture de table simple, commespark.table("main.sales.orders").cache(), les lectures ultérieures scannent toujours une copie complète de la table, donc la mise en cache économise peu. La mise en cache est utile après des opérations coûteuses telles que les jointures, les agrégations et les filtres complexes. -
Ne mettez pas en cache des données que vous n’avez lues qu’une seule fois :
df.cache()calcule et stocke le résultat immédiatement, ce qui prend du temps et du stockage. Si vous lisez le résultat qu’une seule fois, le coût initial n’en vaut pas la peine. -
Utilisez le cache en dérivant à partir du DataFrame mis en cache : Pour lire l’instantané, construisez des opérations ultérieures à partir de la variable DataFrame mise en cache, par exemple
df.select(...)oudf.filter(...). Une DataFrame indépendante construite à partir du même calcul sur les tables sources n’utilise pas le cache. - N’utilisez pas le cache pour le partage de données inter-sessions ou inter-utilisateurs : les données mises en cache sont privées à votre session. D’autres sessions, notebooks, exécutions de tâches, et les utilisateurs ne peuvent pas le lire. Pour partager les résultats calculés entre sessions ou avec d’autres utilisateurs, écrivez-les dans une table permanente.
- Gardez les sessions avec données en cache inférieures à sept jours : voir Cycle de vie et limites de temps. Si votre flux de travail a besoin des données plus longtemps, enregistrez-les dans une table.
-
Appelez
df.unpersist()lorsque vous n’avez plus besoin des données mises en cache : Cela permet à Azure Databricks de libérer l’espace de stockage plus tôt. Après l’appel, le DataFrame et les DataFrames dérivés ne peuvent plus être utilisés. -
Ne pas utiliser
df.unpersist()pour rafraîchir les données :df.unpersist()met fin à l’instantané. Pour capter les modifications dans les tables sources, construisez un nouveau DataFrame à partir des tables sources.
Limitations
La mise en cache DataFrame sur le calcul serverless présente les limitations suivantes :
-
Noms et types de colonnes : Les DataFrames suivants ne peuvent pas être mis en cache. Renommez ou castez les colonnes avant de mettre en cache, par exemple avec
.alias("total_amount").- DataFrames avec des noms de colonnes en double.
- DataFrames avec des noms de colonnes contenant des espaces ou l’un des caractères
,;{}()=, commesum(amount), issus d’une agrégation. - DataFrames avec colonnes d’intervalle.
- DataFrames avec tableaux, maps ou structs contenant des valeurs de type NULL.
- DataFrames sans colonnes, ou avec uniquement des colonnes de type NULL.
-
Références de colonnes : Après avoir mis en cache un DataFrame, vous ne pouvez plus référencer ses colonnes via les DataFrames dont il a été construit. Par exemple, après
oct_15_orders = orders.join(customers, "customer_id")etoct_15_orders.cache(),oct_15_orders.select(orders.amount)augmenteCANNOT_RESOLVE_DATAFRAME_COLUMN. Utilisez plutôtoct_15_orders.amountou"amount". -
API SQL et cache de catalogue : Les instructions SQL cache, telles que
CACHE TABLE, et les méthodes de cache de table despark.catalogne sont pas prises en charge sur le calcul serverless. Voir les limitations de mise en cache. Pour réutiliser un résultat de requête en SQL, utilisez une table temporaire locale de session. -
Requêtes de schéma d’information : Lorsque plusieurs sessions dans un métastore mettent des DataFrames en cache, les requêtes sur
information_schema.volumesetinformation_schema.schematapeuvent être lentes ou expirer. Filtrervolumespar catalogue ne rend pas la requête plus rapide. Les requêtes surinformation_schema.tablesne sont pas affectées.
- Régions Azure Government : La mise en cache DataFrame n'est pas prise en charge sur le calcul serverless dans les régions Azure Government.
-
Paramètres ignorés :
df.persist(storageLevel)ignore le niveau de stockage, etdf.unpersist(blocking)ignoreblocking. Voirdf.persist(storageLevel)etdf.unpersist(blocking).
Migration depuis l’informatique classique
Pour la plupart des charges de travail, la mise en cache sur le calcul serverless donne les mêmes résultats que sur le calcul classique, et le code existant s’exécute sans modifications. Le tableau suivant répertorie les différences.
| Behavior | Informatique sans serveur | Calcul classique |
|---|---|---|
| Correspondance du cache | Seuls les DataFrames mis en cache et les DataFrames qui en sont dérivés utilisent automatiquement le cache. | Toute requête avec la même forme de plan utilise automatiquement le cache. |
| Actualisation des données | Un instantané cohérent pris au moment où vous appelez df.cache(). |
Varie : les données mises en cache sont rafraîchies dans certains cas et fournissent un instantané dans d’autres. |
| Portée du partage | Privé pour votre session. | Partagé entre les sessions au sein du cluster. |
| Matérialisation | Eager : calculé immédiatement lorsque vous appelez df.cache(). |
Évaluation paresseuse : calculé à la première action sur le DataFrame. |
df.unpersist() |
Détruit le DataFrame et libère son instantané de manière déterministe. | Libère le cache en mémoire. L’utilisation ultérieure du DataFrame peut renvoyer les données les plus récentes ou obsolètes, selon le produit et la source de données. |
Voici la description plus détaillée des deux premières différences :
-
Correspondance du cache:
-
Workloads affectés par le changement : La plupart des workloads ne sont pas affectés. Si vous continuez à utiliser la variable DataFrame mise en cache, par exemple avec
df.select(...)oudf.filter(...), le cache fonctionne comme avant. Le changement n’affecte que les charges de travail dans lesquelles une requête DataFrame ou SQL construite indépendamment réutilise le cache car elle a la même forme de plan. En calcul serverless, ces requêtes lisent les tables sources. - Si votre charge de travail est affectée : utilisez la variable DataFrame mise en cache là où vous avez besoin du résultat mis en cache, au lieu de reconstruire la même requête.
-
Workloads affectés par le changement : La plupart des workloads ne sont pas affectés. Si vous continuez à utiliser la variable DataFrame mise en cache, par exemple avec
-
Fraîcheur des données :
- Charges de travail concernées par la modification : La plupart des charges de travail ne sont pas affectées, car il est rare de relire des données mises en cache après avoir écrit dans leurs tables sources. Le changement concerne uniquement les charges de travail qui écrivent dans les tables sources et s’attendent ensuite à ce que le DataFrame mis en cache affiche les nouvelles données.
- Si votre charge de travail est affectée : Après avoir écrit dans les tables sources, construisez un nouveau DataFrame à partir d’elles au lieu de réutiliser celui mis en cache.