Python UDF:t, Scala UDF:t ja monimutkaiset tietotyypit natiivisuoritusmoottorissa

Microsoft Fabric -ohjelman natiivisuoritusmoottori tukee nyt Python-käyttäjän määrittelemiä funktioita (UDF), Scala UDF:iä ja monimutkaisia tietotyyppejä (taulukot, kartat ja rakenteet). Nämä ominaisuudet mahdollistavat ilmaisuvoimaisten Spark-sovellusten kirjoittamisen tinkimättä suorituskyvystä.

Python UDF -tuki

Python on yksi suosituimmista kielistä data-analytiikissä ja data-analytiikassa. Historiallisesti Python UDF:t aiheuttivat merkittäviä ylikuormituksia Sparkissa JVM:n ja Python-työntekijäprosessien sarjallistamiskustannusten vuoksi. Natiivisuoritusmoottori minimoi nämä kalliit siirtymät, mahdollistaen nopeamman suorituksen ilman koodin muutoksia.

Miten Python UDF:t toimivat natiivissa suoritusmoottorissa

Perinteisessä Spark-suoritusmallissa Python UDF:n suoritus sisältää:

  1. Datan muunnos Sparkin sisäisestä formaatista.
  2. Sarjoittaminen ja siirto Python-työskentelyprosesseihin.
  3. Python UDF -suoritus.
  4. Tulosten sarjoittaminen takaisin JVM:ään.
  5. Spark jatkaa teloitusta.

Tämä ajonaikainen liike aiheuttaa sarjallistamis- ja deserialisointikustannuksia, suorittimen tehottomuutta ja rikkinäisiä sarakkeiden suoritusputkia. Natiivisuoritusmoottori vähentää tätä ylikuormitusta optimoimalla tiedonsiirtopolun ja ylläpitämällä vektoroitua käsittelyä mahdollisuuksien mukaan.

Tuetut Python-UDF-tyypit

Natiivisuoritusmoottori tukee:

  • Skalaariset UDF:t: Rivi riviltä Python funktioita, jotka on rekisteröity udf():ään.
  • Vektoroidut (Pandas) UDF:t: Funktiot, jotka on koristeltu @pandas_udf ja jotka toimivat dataerillä Apache Arrow'n avulla tehokkaaseen siirtoon.

Vektoroidut UDF:t saavat suurimmat suorituskyvyn parannukset, koska ne mukautuvat luonnollisesti natiivin suoritusmoottorin sarakkeiden käsittelymalliin.

Esimerkki: Vectorized Python UDF

import pandas as pd
from pyspark.sql.functions import pandas_udf
from pyspark.sql.types import DoubleType

@pandas_udf(DoubleType())
def calculate_discount(price: pd.Series, rate: pd.Series) -> pd.Series:
    return price * (1 - rate)

df = spark.table("sales.transactions")
result = df.withColumn("discounted_price", calculate_discount(df.price, df.discount_rate))
result.show()

Lisäasetuksia ei tarvita natiivisen suoritusmoottorin lisäksi. Nykyiset Python UDF:t hyötyvät automaattisesti.

Scala UDF -tuki

Natiivisuoritusmoottori kiihdyttää myös Scala UDF -laitteita. Koska Scala UDF:t toimivat natiivisti JVM:ssä, moottori voi siirtää tuettuja operaatioita vektoroidulle C++-suorituspolulle, samalla kun Scala UDF -arviointi pysyy tehokkaana saman ajonajan sisällä.

Esimerkki: Scala UDF

import org.apache.spark.sql.functions.udf

val toUpperCase = udf((s: String) => s.toUpperCase)
val df = spark.table("catalog.customers")
val result = df.withColumn("name_upper", toUpperCase(df("name")))
result.show()

Scala UDF:t, jotka toimivat tuetuilla tietotyypeillä, nopeutuvat ilman koodin muutoksia, kun natiivisuoritusmoottori on käytössä.

Monimutkaisten tietotyyppien tuki

Nykyaikaiset järvimajojen arkkitehtuurit perustuvat puolistrukturoituun ja sisäkkäiseen dataan. Natiivisuoritusmoottori tarjoaa nyt optimoidun tuen:

Tietotyyppi Description Esimerkki käyttötapauksesta
Valikoima Järjestetty alkioiden kokoelma Tapahtumatunnisteet, tuotekategoriat
Kartta Avain-arvo-parit Konfiguraatio-ominaisuudet, metatiedot
Rakenne Nimettyjä kenttiä eri tyypeillä Sisäkkäiset asiakastietueet, osoiteobjektit

Monimutkaisille tyypeille tuetut operaatiot

Natiivisuoritusmoottori nopeuttaa yleisiä operaatioita monimutkaisilla tietotyypeillä:

  • Taulukkofunktiot: explode, array_contains, size, flatten, , transform
  • Karttafunktiot: map_keys, map_values, element_at
  • Rakenteen käyttö: Pistemerkintäkentän käyttö, getField
  • Sisäkkäiset yhdistelmät: Rakenteiden taulukot, kartat taulukon arvoilla

Esimerkki: Työskentely taulukoiden ja rakenteiden kanssa

from pyspark.sql.functions import explode, col, size

# Read data with nested schema
df = spark.table("events.telemetry")

# Operations on arrays - accelerated by native engine
result = (df
    .filter(size(col("tags")) > 0)
    .select(
        col("event_id"),
        col("metadata.source"),  # Struct field access
        explode(col("tags")).alias("tag")
    )
)
result.show()

Esimerkki: Työskentely karttojen kanssa

from pyspark.sql.functions import map_keys, map_values, col

df = spark.table("config.settings")

# Map operations - accelerated by native engine
result = (df
    .select(
        col("setting_id"),
        map_keys(col("properties")).alias("keys"),
        map_values(col("properties")).alias("values")
    )
)
result.show()

Suorituskykytulokset

Sisäinen vertailu osoittaa merkittäviä parannuksia työkuormissa, jotka käyttävät Python UDF:ää ja monimutkaisia tietotyyppejä:

Työkuormatyyppi Suorituskyvyn parantaminen
Vektoroidut Python UDF:t Jopa 5,76 kertaa nopeampi
Skalaariset Python UDF:t Jopa 1,08 kertaa nopeampi
TPC-DS päästä päähän (monimutkaisilla tyypeillä) Jopa 2,35 kertaa nopeampi

Nämä hyödyt johtuvat vähentyneestä sarjallistamiskulusta, parantuneesta vektorointista ja päästä päähän -sarakkeiden suorituksesta.

Hyödyt kehittyneille järvimajojen malleille

Monimutkaisen tietotyyppin kiihdytys on erityisen tärkeää seuraavissa tapauksissa:

  • Z-ORDER-optimointi: Sisäkkäiset sarakkeet osallistuvat optimoituun datan asetteluun.
  • Nesteen klusterointi: Monimutkaiset kolonnit hyötyvät klusteroitumisesta ilman tasoittumista.
  • Puolistrukturoitu analytiikka: JSON-hyötykuormat ja tapahtumavirrat pysyvät sisäkkäisenä luonnolliseen kyselyyn.
  • Tapahtumalähtöiset arkkitehtuurit: Telemetria ja IoT-data säilyttävät hierarkkisen rakenteensa.

Sen sijaan, että tasoittaisit dataa tai uudelleenjärjestelisit putkia suorituskyvyn vuoksi, työskentele luonnollisesti monimutkaisten skeemojen kanssa säilyttäen samalla korkean suoritustehokkuuden.

Toiminnon käyttöönotto

Python UDF:n, Scala UDF:n ja monimutkaisten tietotyyppien tuki on käytettävissä, kun natiivisuoritusmoottori on käytössä. Lisäkonfiguraatiota ei tarvita.

Natiivin suoritusmoottorin ottamiseksi käyttöön katso Fabric Data Engineeringin natiivisuoritusmoottori.

Edellytykset

Rajoitukset

  • Kaikki Python-kirjastot eivät ole tuettuja vektoroidussa polussa. Kirjastot, jotka vaativat mielivaltaista Python-objektien sarjoittamista, saattavat silti laukaista varasuunnitelman.
  • Syvälle sisäkkäiset kompleksityypit (esimerkiksi rakenteiden karttataulukot) saattavat palata JVM-moottoriin tietyissä operaatioissa.
  • ANSI-tilaa ei tueta natiivisuoritusmoottorilla.