Pular para o conteúdo principal

DataFrames de cache no compute serverless

info

Visualização

Esse recurso está em Prévia Pública. Os administradores do Workspace podem controlar o acesso ao cache de DataFrame em compute serverless na página Pré-visualizações . Consulte Gerenciar prévias do Databricks.

No compute serverless, você pode armazenar em cache um DataFrame com df.cache() ou df.persist() para reutilizar um resultado caro em sua sessão. O Databricks calcula o DataFrame quando você chama cache() e materializa o resultado como um snapshot. O DataFrame e os DataFrames que você cria a partir dele leem o snapshot pelo restante da sua sessão em vez de recalculá-lo.

Requisitos​

  • A prévia do cache de DataFrame em compute Serverless está habilitada para seu Workspace (habilitada por default). Os administradores do Workspace podem desativá-lo na página Pré-visualizações . A prévia não está disponível em Workspace com o perfil de segurança de compliance habilitado. Consulte Gerenciar prévias no nível do workspace.
  • Notebooks e jobs em compute Serverless devem usar a versão de ambiente 5 ou acima.
  • O Databricks Connect para Python deve ser 18.1.8 ou acima, e o Databricks Connect para Scala deve ser 18.1.5 ou acima.

Clientes mais antigos recebem o erro CACHE_REQUIRES_NEWER_CLIENT_ON_SERVERLESS_GC.

Quando usar o cache de DataFrame em compute serverless​

Faça cache de um DataFrame em compute serverless quando precisar:

  • Reutilize o resultado de um join, agregação ou filtro caro várias vezes na mesma sessão.
  • Compute um micro-batch de transmissão uma vez em uma função foreachBatch e, em seguida, grave-o em vários coletores.
  • Ensine ou ajuste vários modelos do machine learning usando os mesmos dados de recursos preparados.
  • Mantenha um Snapshot estável enquanto executa os passos de uma análise, mesmo que as tabelas de origem sejam alteradas.

Consulte Práticas recomendadas.

Cache de APIs de DataFrame em compute serverless​

O exemplo a seguir armazena em cache um dia de pedidos combinados com dados do cliente, compute a receita total do dia, acrescenta a receita por região a uma tabela de relatório e, em seguida, libera o cache. Ambos os resultados leem o snapshot em cache em vez de executar o join novamente.

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

Nas descrições de API a seguir, df representa qualquer DataFrame em sua sessão, como oct_15_orders no exemplo anterior.

df.cache()​

Computes df imediatamente e armazena em cache o resultado como um snapshot para o restante da sua sessão.

  • Retorna : O mesmo DataFrame em cache, df, agora com base no snapshot em vez do cálculo em suas tabelas de origem. Veja o comportamento a seguir.
  • Comportamento :
    • Executa a query do DataFrame imediatamente e materializa o resultado como um snapshot antes que a chamada retorne.
    • Após a chamada, df e o DataFrame retornado (df em si) são baseados no snapshot. Eles não estão mais conectados à computação nas tabelas de origem, portanto, lêem o snapshot em vez de recomputar a query.
    • DataFrames derivados de df, diretamente ou através de outros DataFrames derivados, leem o Snapshot automaticamente em vez de executar a query original novamente. Consulte Ler o snapshot.
    • O snapshot é local para sua sessão. Somente a sessão que armazenou em cache df pode lê-la. Consulte Isolamento e privilégios.
    • O Snapshot dura até o fim da sessão, por no máximo sete dias. O Databricks então recupera automaticamente seu armazenamento em segundo plano. Chamar df.unpersist() permite que ele recupere o armazenamento mais cedo. Consulte Ciclo de vida e limites de tempo e Armazenamento e limpeza.
    • Se o cálculo de df falhar, df.cache() gerará o erro e df não será armazenado em cache.
    • Chamar df.cache() em um DataFrame que já está em cache não faz nada. df não é computado novamente.

O snapshot é fixado após você chamar df.cache(). Dados gravados posteriormente nas tabelas das quais df lê, e alterações de esquema nessas tabelas, como colunas adicionadas ou renomeadas, não o afetam. Para recalcular com base nos dados mais recentes, crie o DataFrame novamente a partir das tabelas de origem e faça o cache do novo DataFrame, se precisar.

Ler o snapshot​

No compute serverless, a correspondência de cache é baseada na derivação do DataFrame. Após df.cache(), apenas os seguintes DataFrames leem o Snapshot automaticamente em vez de recomputar a query nas tabelas de origem:

  • O DataFrame que você armazenou em cache, df.
  • DataFrames derivados de df, por exemplo, com select(), filter(), groupBy() ou join().
  • DataFrames posteriormente encadeados a partir desses DataFrames derivados.

Um novo DataFrame que repete a mesma query lê as tabelas de origem, embora sua lógica seja idêntica, porque não é derivado de df.

Isso torna a correspondência de cache explícita e sob seu controle: um DataFrame lê dados em cache apenas quando você o deriva de um DataFrame em cache. Todos os outros DataFrames lêem as tabelas de origem.

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

Como df lê o snapshot em vez dos DataFrames a partir dos quais foi criado, você não pode referenciar as colunas de df por meio desses DataFrames. Consulte Limitações.

df.persist(storageLevel)​

Um alias de df.cache() que aceita um nível de armazenamento.

  • Parâmetros :
    • storageLevel (opcional): Um StorageLevel, como StorageLevel.DISK_ONLY. o compute serverless aceita qualquer nível de armazenamento e o ignora. O snapshot é armazenado da mesma maneira para cada nível de armazenamento, e df.storageLevel retorna StorageLevel.DISK_ONLY.

O valor de retorno e o comportamento são os mesmos que df.cache().

df.unpersist(blocking)​

Libera o snapshot em cache de df e destrói o DataFrame.

  • Parâmetros :

    • blocking (opcional): Ignorado. df.unpersist() retorna imediatamente para qualquer valor.
  • Retorna : O mesmo DataFrame, df, agora destruído.

  • Comportamento :

    • Marca o snapshot como pronto para ser recuperado. O Databricks exclui os dados em cache e recupera o armazenamento em segundo plano.
    • Destrói df: df e todos os DataFrames derivados dele anteriormente não são mais utilizáveis, e qualquer query subsequente neles gera CACHE_DATAFRAME_ACCESS_AFTER_UNCACHE. Se você armazenar em cache um DataFrame derivado de df antes de chamar df.unpersist(), esse DataFrame permanece utilizável porque ele tem seu próprio snapshot.
    • Para continuar trabalhando com a mesma fonte de dados, crie um novo DataFrame a partir da fonte de dados original, em vez de reutilizar o DataFrame não armazenado em cache.
    • Chamar df.unpersist() em um DataFrame que nunca foi armazenado em cache, ou que já foi desarmazenado, é uma operação sem efeito.

Chame df.unpersist() quando você não precisar mais dos dados em cache, por exemplo, quando nenhum o passo posterior em seu notebook ou job os ler. Isso permite que o Databricks recupere o armazenamento mais cedo. Não use df.unpersist() para refresh dados. Para trabalhar com os dados mais recentes, crie um novo DataFrame a partir das tabelas de origem.

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

df.storageLevel​

Obtém o nível de armazenamento de df.

  • Retorna : StorageLevel.DISK_ONLY enquanto df está em cache. StorageLevel.NONE antes de armazená-lo em cache e depois de chamar df.unpersist().
Python
from pyspark import StorageLevel

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

Para as assinaturas de método, consulte a referência do PySpark para cache, persist, unpersist e storageLevel.

Limites de tempo e ciclo de vida​

Os dados em cache existem apenas dentro da sessão do Databricks onde você os armazena em cache. Torna-se inacessível quando a sessão termina e dura no máximo sete dias. Após o limite de sete dias, o uso de um DataFrame em cache gera um erro em vez de ler as tabelas de origem novamente. Para fazer cache novamente, comece uma nova sessão.

Armazenamento e limpeza​

O Databricks gerencia o armazenamento de dados em cache automaticamente. Dados armazenados em cache são armazenados no armazenamento em cloud, com o local de armazenamento específico dependendo do tipo de seu Workspace:

Depois que os dados armazenados em cache ficam inacessíveis, o Databricks recupera automaticamente o armazenamento em segundo plano. Isso inclui casos em que a sessão termina devido a uma desconexão ou falha. Chamar df.unpersist() permite que o Databricks recupere o armazenamento mais cedo.

Isolamento e privilégios​

Qualquer usuário que possa realizar a execução de código em compute Serverless pode armazenar um DataFrame em cache. Você não precisa de nenhum privilégio extra.

Os dados armazenados em cache fornecem isolamento em nível de sessão. Apenas a sessão que armazenou em cache um DataFrame pode ler seus dados armazenados em cache. Outros usuários não podem acessá-lo, incluindo outros usuários do mesmo Notebooks.

Os dados em cache contêm o que você tinha permissão para ler quando os armazenou em cache. As alterações de permissão, os filtros de linha e as máscaras de coluna aplicadas às tabelas de origem posteriormente não se aplicam aos dados em cache.

Práticas recomendadas​

  • Cache quando precisar de um Snapshot estável : Se você fizer a execução de várias transformações, agregações ou drill-downs nos mesmos dados compute, o Snapshot fornecerá a eles uma linha de base consistente que não muda quando as tabelas de origem mudam.
  • Cache de cálculos dispendiosos, não leituras de tabelas simples : df.cache() materializa o resultado da query e as leituras posteriores verificam esse snapshot. Se você armazenar em cache uma leitura de tabela simples, como spark.table("main.sales.orders").cache(), as leituras posteriores ainda verificam uma cópia completa da tabela, portanto, o cache economiza pouco. O cache compensa depois de trabalhos dispendiosos, como joins, agregações e filtros complexos.
  • Não faça cache de dados lidos apenas uma vez : df.cache() compute e armazena o resultado imediatamente, o que leva tempo e armazenamento. Se você ler o resultado apenas uma vez, o custo inicial não vale a pena.
  • Use o cache derivando do DataFrame armazenado : Para ler o snapshot, crie operações subsequentes a partir da variável DataFrame armazenada, por exemplo df.select(...) ou df.filter(...). Um DataFrame independente criado a partir do mesmo cálculo nas tabelas de origem não usa o cache.
  • Não use o cache para compartilhamento de dados entre sessões ou entre usuários : os dados em cache são privados à sua sessão. Outras sessões, notebooks, execuções de jobs e usuários não podem lê-lo. Para compartilhar resultados computados entre sessões ou com outros usuários, grave-os em uma tabela permanente.
  • Mantenha as sessões com dados em cache por menos de sete dias : veja Ciclo de vida e limites de tempo. Se seu fluxo de trabalho precisar dos dados por mais tempo, grave-os em uma tabela.
  • Chame df.unpersist() quando não precisar mais dos dados armazenados em cache : Isso permite que o Databricks recupere o armazenamento mais cedo. Após a chamada, o DataFrame e os DataFrames derivados dele não podem ser usados.
  • Não use df.unpersist() para fazer refresh dos dados : df.unpersist() encerra a vida útil do Snapshot. Para incorporar as alterações nas tabelas de origem, crie um novo DataFrame a partir das tabelas de origem.

Limitações​

O armazenamento em cache de DataFrame em compute serverless tem as seguintes limitações:

  • Nomes e tipos de colunas : Os seguintes DataFrames não podem ser armazenados em cache. Renomeie ou converta as colunas antes de armazenar em cache, por exemplo, com .alias("total_amount").

    • DataFrames com nomes de coluna duplicados.
    • DataFrames com nomes de coluna que contêm espaços ou qualquer um dos caracteres ,;{}()=, como sum(amount) de uma agregação.
    • DataFrames com colunas de intervalo.
    • DataFrames com matrizes, mapas ou estruturas que contêm valores do tipo NULL.
    • DataFrames sem colunas, ou apenas com colunas do tipo NULL.
  • Referências de coluna : depois de armazenar um DataFrame em cache, não é possível referenciar suas colunas por meio dos DataFrames dos quais ele foi criado. Por exemplo, após oct_15_orders = orders.join(customers, "customer_id") e oct_15_orders.cache(), oct_15_orders.select(orders.amount) gera CANNOT_RESOLVE_DATAFRAME_COLUMN. Use oct_15_orders.amount ou "amount" em vez disso.

  • APIs de cache SQL e de catálogo : instruções de cache SQL, como CACHE TABLE, e os métodos de cache de tabela de spark.catalog não são suportados no compute serverless. Consulte Limitações de cache. Para reutilizar um resultado de query em SQL, use uma tabela temporária local de sessão.

  • Queries de esquema de informação : Quando muitas sessões em um metastore fazem cache de DataFrames, as consultas em information_schema.volumes e information_schema.schemata podem ser lentas ou ter o tempo limite excedido. Filtrar volumes por catálogo não torna a query mais rápida. As consultas em information_schema.tables não são afetadas.

  • Parâmetros ignorados : df.persist(storageLevel) ignora o nível de armazenamento e df.unpersist(blocking) ignora blocking. Consulte df.persist(storageLevel) e df.unpersist(blocking).

Migrar de compute clássico​

Para a maioria das cargas de trabalho, o cache em compute Serverless oferece os mesmos resultados que o compute clássico, e a execução do código existente ocorre sem alterações. A tabela a seguir lista as diferenças.

Comportamento

computação sem servidor

Compute clássico

Correspondência de cache

Apenas o DataFrame em cache e os DataFrames derivados dele usam o cache automaticamente.

Qualquer query com o mesmo formato de plano usa automaticamente o cache.

Atualização dos dados

Um snapshot consistente obtido no momento em que você chama df.cache().

Variável: os dados em cache são atualizados em certos casos e servem um snapshot em outros.

Escopo de compartilhamento

Privado para a sua sessão.

Compartilhado entre sessões dentro do cluster.

Materialização

Eager: compute imediatamente quando você chama df.cache().

Lento: computado na primeira ação no DataFrame.

df.unpersist()

Destrói o DataFrame e libera seu snapshot deterministicamente.

Libera o cache em memória. O uso posterior do DataFrame pode obter os dados mais recentes ou obsoletos, dependendo do produto e da fonte de dados.

Comportamento

computação sem servidor

Compute clássico

Correspondência de cache

Apenas o DataFrame em cache e os DataFrames derivados dele usam o cache automaticamente.

Qualquer query com o mesmo formato de plano usa automaticamente o cache.

Atualização dos dados

Um snapshot consistente obtido no momento em que você chama df.cache().

Variável: os dados em cache são atualizados em certos casos e servem um snapshot em outros.

Escopo de compartilhamento

Privado para a sua sessão.

Compartilhado entre sessões dentro do cluster.

Materialização

Eager: compute imediatamente quando você chama df.cache().

Lento: computado na primeira ação no DataFrame.

df.unpersist()

Destrói o DataFrame e libera seu snapshot deterministicamente.

Libera o cache em memória. O uso posterior do DataFrame pode obter os dados mais recentes ou obsoletos, dependendo do produto e da fonte de dados.

A seguir, as duas primeiras diferenças são descritas em mais detalhes:

  • Correspondência de cache :

    • Cargas de trabalho afetadas pela alteração : a maioria das cargas de trabalho não foi afetada. Se você continuar usando a variável DataFrame armazenada em cache, por exemplo, com df.select(...) ou df.filter(...), o cache funciona como antes. A alteração afeta apenas cargas de trabalho onde um DataFrame construído independentemente ou uma query SQL reutiliza o cache porque tem a mesma forma de plano. No Serverless compute, essas query leem as tabelas de origem.
    • Se sua carga de trabalho for afetada : Use a variável DataFrame em cache onde precisar do resultado em cache, em vez de criar a mesma query novamente.
  • Atualização dos dados :

    • Cargas de trabalho afetadas pela alteração : A maioria das cargas de trabalho não é afetada, pois ler os dados em cache novamente após a gravação nas tabelas de origem não é comum. A alteração afeta apenas as cargas de trabalho que gravam nas tabelas de origem e esperam que o DataFrame em cache mostre os novos dados.
    • Se sua carga de trabalho for afetada : após gravar nas tabelas de origem, crie um novo DataFrame a partir delas em vez de reutilizar o que está em cache.

Outros recursos​