Python UDF-eket, Scala UDF-eket és összetett adattípusokat natív végrehajtási motorban

Az Microsoft Fabric natív végrehajtási motorja mostantól támogatja Python felhasználó által definiált függvényeket (UDF-eket), a Scala UDF-eket és az összetett adattípusokat (tömböket, térképeket és szerkezeteket). Ezek a képességek lehetővé teszik expresszív Spark-alkalmazások írását anélkül, hogy feláldozná a teljesítményt.

Python UDF-támogatás

Python az adatelemzés és az adatelemzés egyik legnépszerűbb nyelve. Korábban Python UDF-ek jelentős többletterhelést vezettek be a Sparkban a JVM és Python feldolgozói folyamatok közötti szerializálási költségek miatt. A natív végrehajtási motor minimalizálja ezeket a költséges áttűnéseket, így kódmódosítások nélkül gyorsabb végrehajtást tesz lehetővé.

Az Python UDF-ek működése natív végrehajtási motorban

Egy hagyományos Spark-végrehajtási modellben Python UDF-végrehajtás a következőket foglalja magában:

  1. Adatkonvertálás a Spark belső formátumából.
  2. Szerializálás és átvitel Python feldolgozói folyamatokba.
  3. Python UDF-végrehajtás.
  4. Az eredmények szerializálása vissza a JVM-be.
  5. A Spark folytatja a végrehajtást.

Ez a futásidejű mozgás szerializálási/deszerializálási költségeket, processzorhiányt és hibás oszlopos végrehajtási folyamatokat hoz létre. A natív végrehajtási motor csökkenti ezt a többletterhelést az adatátviteli útvonal optimalizálásával és a vektoros feldolgozás lehetőség szerinti fenntartásával.

Támogatott Python UDF-típusok

A natív végrehajtási motor a következőket támogatja:

  • Scalar UDFs: a udf() használatával regisztrált, soronként működő Python-függvények.
  • Vektorizált (Pandas) UDF-ek: Olyan függvények@pandas_udf, amelyek adatkötegeken működnek az Apache Arrow használatával a hatékony átvitel érdekében.

A vektorizált UDF-ek a legnagyobb teljesítménynövekedést látják, mivel természetesen igazodnak a natív végrehajtási motor oszlopos feldolgozási modelljéhez.

Példa: Vektorizált 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()

A natív végrehajtási motor engedélyezésén túl nincs szükség további konfigurációra. A meglévő Python UDF-ek automatikusan előnyösek.

Scala UDF-támogatás

A natív végrehajtási motor felgyorsítja a Scala UDF-eket is. Mivel a Scala UDF-ek natív módon futnak a JVM-ben, a motor képes kiosztani a támogatott műveleteket a vektorizált C++ végrehajtási útvonalra, miközben a Scala UDF kiértékelése hatékonyan működik ugyanazon a futtatókörnyezeten belül.

Példa: 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()

A támogatott adattípusokon működő Scala UDF-ek kódmódosítások nélkül gyorsulnak fel, ha a natív végrehajtási motor engedélyezve van.

Összetett adattípusok támogatása

A modern lakehouse-architektúrák részben strukturált és beágyazott adatoktól függenek. A natív végrehajtási motor mostantól optimalizált támogatást nyújt a következőkhöz:

Adattípus Leírás Példa használati esetre
Tömb Elemek rendezett gyűjteménye Eseménycímkék, termékkategóriák
Térkép Kulcs-érték párok Konfigurációs tulajdonságok, metaadatok
Struct Különböző típusú elnevezett mezők Beágyazott ügyfélrekordok, címobjektumok

Összetett típusok esetén támogatott műveletek

A natív végrehajtási motor felgyorsítja az összetett adattípusok gyakori műveleteit:

  • Tömbfüggvények: explode, array_contains, size, flatten, transform
  • Leképezési függvények: map_keys, map_values, element_at
  • Struktúraelérés: mezőelérés pontozott jelöléssel, getField
  • Beágyazott kombinációk: Strukturált tömbök, tömbértékekkel rendelkező térképek

Példa: Tömbök és struktúrák használata

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

Példa: Térképek használata

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

Teljesítményeredmények

A belső teljesítményértékelés jelentős fejlesztéseket mutat be az Python UDF-eket és összetett adattípusokat használó számítási feladatokban:

Terhelés típusa Teljesítménybeli javulás
Vektorizált Python UDF-ek Akár 5,76-szor gyorsabb
Skaláris Python UDF-ek Akár 1,08-szor gyorsabb
TPC-DS elejétől a végéig (összetett típusokkal) Akár 2,35-szer gyorsabb

Ezek az előnyök a csökkentett szerializálási többletterhelésből, a javított vektorizációból és a teljes körű oszlopos végrehajtásból adódnak.

A fejlett lakehouse-minták előnyei

Az összetett adattípus-gyorsítás különösen fontos a következő esetekben:

  • Z-ORDER optimalizálás: A beágyazott oszlopok részt vesznek az optimalizált adatelrendezésben.
  • Folyékony fürtözés: Az összetett típusú oszlopok simítás nélkül is élvezhetik a fürtözés előnyeit.
  • Félig strukturált elemzés: A JSON hasznos terhek és az eseményfolyamok továbbra is beágyazódnak a természetes lekérdezéshez.
  • Eseményvezérelt architektúrák: A telemetriai és az IoT-adatok megőrzik hierarchikus struktúrájukat.

Az adatok összeolvasztása vagy a folyamatok teljesítményre való átszervezése helyett természetesen összetett sémákkal dolgozhat, miközben magas végrehajtási hatékonyságot biztosít.

A funkció engedélyezése

Python UDF, Scala UDF és összetett adattípus támogatása akkor érhető el, ha a natív végrehajtási motor engedélyezve van. Nincs szükség további konfigurációra.

A natív végrehajtási motor engedélyezéséhez tekintse meg a Fabric Data Engineering natív végrehajtási motorja című témakört.

Prerequisites

Limitations

  • A vektoros elérési úton nem minden Python kódtár támogatott. Azok a könyvtárak, amelyek tetszőleges Python-objektumok szerializálását igénylik, továbbra is visszalépést válthatnak ki.
  • A mélyen egymásba ágyazott összetett típusok (például a struktúrák leképezéseit tartalmazó tömbök) bizonyos műveletek esetén visszatérhetnek a JVM-motor használatához.
  • Az ANSI mód nem támogatott a natív végrehajtási motorral.