Compartilhar via


O que são UDFs (funções definidas pelo usuário)?

Uma UDF (função definida pelo usuário) é uma função definida por um usuário, que permite que lógica personalizada seja reutilizada no ambiente do usuário. O Azure Databricks tem suporte para muitos tipos diferentes de UDFs para permitir a distribuição de lógica extensível. Este artigo apresenta alguns dos pontos fortes e das limitações gerais das UDFs.

Observação

Nem todas as formas de UDFs estão disponíveis em todos os ambientes de execução no Azure Databricks. Se você estiver trabalhando com o Catálogo do Unity, consulte UDFs (funções definidas pelo usuário) no Catálogo do Unity.

Definindo lógica personalizada sem penalidades de serialização

O Azure Databricks herda grande parte de seus comportamentos de UDF do Apache Spark, incluindo as limitações de eficiência em relação a muitos tipos de UDFs. Confira Quais UDFs são mais eficientes?.

Você pode modularizar seu código com segurança sem se preocupar com possíveis compensações de eficiência associadas a UDFs. Para fazer isso, você deve definir sua lógica como uma série de métodos internos do Spark usando DataFrames SQL ou Spark. Por exemplo, as seguintes funções SQL e Python combinam métodos internos do Spark para definir uma conversão de unidade como função reutilizável:

SQL

CREATE FUNCTION convert_f_to_c(unit STRING, temp DOUBLE)
RETURNS DOUBLE
RETURN CASE
  WHEN unit = "F" THEN (temp - 32) * (5/9)
  ELSE temp
END;

SELECT convert_f_to_c(unit, temp) AS c_temp
FROM tv_temp;

Python

def convertFtoC(unitCol, tempCol):
  from pyspark.sql.functions import when
  return when(unitCol == "F", (tempCol - 32) * (5/9)).otherwise(tempCol)

from pyspark.sql.functions import col

df_query = df.select(convertFtoC(col("unit"), col("temp"))).toDF("c_temp")
display(df_query)

Para executar as UDFs acima, você pode criar dados de exemplo.

Quais UDFs são mais eficientes?

As UDFs podem introduzir gargalos de processamento significativos na execução do código. O Azure Databricks usa vários otimizadores diferentes automaticamente para código escrito com a sintaxe do Apache Spark, SQL e Delta Lake incluídas. Quando a lógica personalizada é introduzida pelas UDFs, esses otimizadores não têm a capacidade de planejar tarefas com eficiência em torno dessa lógica personalizada. Além disso, a lógica executada fora da JVM tem custos adicionais relacionados à serialização de dados.

Observação

O Azure Databricks otimiza várias funções usando o Photon se você usa a computação habilitada para Photon. Somente as funções que encadeiam os comandos Spark SQL de DataFrame podem ser otimizadas pelo Photon.

Algumas UDFs são mais eficientes do que outras. Em termos de desempenho:

  • Funções internas serão mais rápidas devido aos otimizadores do Azure Databricks.
  • O código executado na JVM (UDFs Scala, Java e Hive) será mais rápido que UDFs Python.
  • UDFs Pandas usam Arrow para reduzir os custos de serialização associados a UDFs Python.
  • As UDFs do Python funcionam bem para a lógica de procedimento, mas devem ser evitadas para cargas de trabalho de ETL de produção em grandes conjuntos de dados.

Observação

No Databricks Runtime 12.2 LTS e versões anteriores, UDFs escalares do Python e UDFs do Pandas não têm suporte no Catálogo do Unity em clusters que usam o modo de acesso compartilhado. Esses UDFs têm suporte no Databricks Runtime 13.3 LTS e versões superiores para todos os modos de acesso.

No Databricks Runtime 14.1 e anteriores, UDFs escalares do Scala não têm suporte no Catálogo do Unity em clusters que usam o modo de acesso compartilhado. Esses UDFs têm suporte para todos os modos de acesso no Databricks Runtime 14.2 e superior.

No Databricks Runtime 13.3 LTS e versões superiores, é possível registrar UDFs escalares do Python no Catálogo do Unity usando a sintaxe SQL. Consulte UDFs (funções definidas pelo usuário) no Catálogo do Unity.

Tipo Otimizado Ambiente de execução
UDF do Hive No JVM
UDF Python No Python
UDF Pandas No Python (Arrow)
UDF Scala No JVM
Spark SQL Sim JVM (Photon)
DataFrame Spark Yes JVM (Photon)

Quando você deve usar uma UDF?

Um dos principais benefícios das UDFs é que elas permitem que os usuários expressem lógica em linguagens familiares, reduzindo o custo humano associado à refatoração de código. Para consultas ad hoc, limpeza de dados manual, análise de dados exploratória e a maioria das operações em conjuntos de dados de pequeno ou médio porte, é improvável que os custos de sobrecarga de latência associados a UDFs superem os custos associados à refatoração de código.

Para trabalhos ETL, operações de streaming, operações em conjuntos de dados muito grandes ou outras cargas de trabalho executadas regularmente ou continuamente, a lógica de refatoração para usar métodos nativos do Apache Spark paga rapidamente dividendos.

Dados de exemplo para UDFs de exemplo

Os exemplos de código neste artigo usam UDFs para converter temperaturas entre Celcius e Farenheit. Para executar essas funções, crie um conjunto de dados de exemplo com o seguinte código Python:

import numpy as np
import pandas as pd

Fdf = pd.DataFrame(np.random.normal(55, 25, 10000000), columns=["temp"])
Fdf["unit"] = "F"

Cdf = pd.DataFrame(np.random.normal(10, 10, 10000000), columns=["temp"])
Cdf["unit"] = "C"

df = spark.createDataFrame(pd.concat([Fdf, Cdf]).sample(frac=1))

df.cache().count()
df.createOrReplaceTempView("tv_temp")