Megosztás a következőn keresztül:


Az Apache Spark-kód ismertetése U-SQL-fejlesztők számára

Fontos

Az Azure Data Lake Analytics 2024. február 29-én megszűnt. További információ ezzel a bejelentéssel.

Az adatelemzéshez a szervezet használhatja a Azure Synapse Analyticset vagy a Microsoft Fabricet.

Ez a szakasz magas szintű útmutatást nyújt az U-SQL-szkriptek Apache Sparkra való átalakításához.

Az U-SQL és a Spark nyelvének és feldolgozási paradigmáinak megismerése

Mielőtt megkezdené az Azure Data Lake Analytics U-SQL-szkriptjeinek Sparkba való migrálását, hasznos megérteni a két rendszer általános nyelv- és feldolgozási filozófiáját.

Az U-SQL egy SQL-szerű deklaratív lekérdezési nyelv, amely adatfolyam-paradigmát használ, és lehetővé teszi a .NET-ben (például C#), Pythonban és R-ben írt felhasználói kód egyszerű beágyazását és horizontális felskálázását. A felhasználói bővítmények egyszerű kifejezéseket vagy felhasználó által definiált függvényeket implementálhatnak, de lehetővé teszik a felhasználó számára az úgynevezett felhasználó által definiált operátorok implementálását is, amelyek egyéni operátorokat implementálnak a sorhalmazszintű átalakítások, kinyerések és kimenetek írásához.

A Spark egy horizontálisan felskálázott keretrendszer, amely számos nyelvi kötést kínál a Scala, a Java, a Python, a .NET stb. nyelvben, ahol a kódot elsősorban ezen nyelvek egyikében írja, rugalmas elosztott adatkészleteknek (RDD), adatkereteknek és adatkészleteknek nevezett adat absztrakciókat hoz létre, majd linq-szerű tartományspecifikus nyelvet (DSL) használ az átalakításukhoz. A SparkSQL-t deklaratív alnyelvként is biztosítja az adatkereten és az adathalmaz-absztrakciókon. A DSL a műveletek, átalakítások és műveletek két kategóriáját biztosítja. Ha átalakításokat alkalmaz az adat absztrakciókra, az nem hajtja végre az átalakítást, hanem egy művelettel kiértékelendő végrehajtási tervet hoz létre (például az eredményt egy ideiglenes táblába vagy fájlba írja, vagy kinyomtatja az eredményt).

Így amikor egy U-SQL-szkriptet Spark-programba fordít, el kell döntenie, hogy melyik nyelvet szeretné használni legalább az adatkeret absztrakciójának létrehozásához (amely jelenleg a leggyakrabban használt adat absztrakció), és hogy a deklaratív adatfolyam-átalakításokat a DSL vagy a SparkSQL használatával szeretné-e megírni. Néhány összetettebb esetben előfordulhat, hogy fel kell osztania az U-SQL-szkriptet egy Spark-sorozatra, valamint a Azure Batch vagy Azure Functions végrehajtott egyéb lépésekre.

Az Azure Data Lake Analytics emellett U-SQL-t is kínál egy kiszolgáló nélküli feladatszolgáltatási környezetben, ahol az erőforrások minden feladathoz ki vannak foglalva, míg a Spark, az Azure Databricks és az Azure HDInsight Azure Synapse a Sparkot fürtszolgáltatás vagy úgynevezett Spark-készletsablonok formájában kínálják. Az alkalmazás átalakításakor figyelembe kell vennie a fürtök vagy készletek létrehozásának, méretezésének, méretezésének és leszerelésének következményeit.

U-SQL-szkriptek átalakítása

Az U-SQL-szkriptek a következő feldolgozási mintát követik:

  1. Az adatok a strukturálatlan fájlokból, a EXTRACT utasításból, egy hely- vagy fájlkészlet-specifikációból, valamint a beépített vagy felhasználó által definiált kinyerőből és a kívánt sémából, illetve U-SQL-táblákból (felügyelt vagy külső táblákból) származnak. Sorhalmazként jelenik meg.
  2. A sorhalmazok több U-SQL-utasításban lesznek átalakítva, amelyek U-SQL-kifejezéseket alkalmaznak a sorhalmazokra, és új sorhalmazokat hoznak létre.
  3. Végül az eredményül kapott sorhalmazok a hely(ek)et és egy beépített vagy felhasználó által definiált kimenetet megadó utasítással OUTPUT vagy egy U-SQL-táblába kerülnek.

A szkriptet a rendszer lazán értékeli ki, ami azt jelenti, hogy minden egyes kinyerési és átalakítási lépés egy kifejezésfává lesz összeállítva, és globálisan ki lesz értékelve (az adatfolyam).

A Spark-programok hasonlóak ahhoz, hogy a Spark-összekötőkkel beolvassa az adatokat, és létrehozza az adatkereteket, majd alkalmazza az átalakításokat az adatkereteken a LINQ-szerű DSL vagy SparkSQL használatával, majd írja be az eredményt fájlokba, ideiglenes Spark-táblákba, bizonyos programozási nyelvtípusokba vagy a konzolba.

.NET-kód átalakítása

A U-SQL kifejezésnyelve C# és különböző módszereket kínál az egyéni .NET-kódok felskálázására felhasználó által definiált függvényekkel, felhasználó által definiált operátorokkal és felhasználó által definiált összesítőkkel.

Azure Synapse és az Azure HDInsight Spark is natív módon támogatja a .NET-kód Apache Sparkhoz készült .NET-kóddal történő végrehajtását. Ez azt jelenti, hogy a Sparkkal esetleg újra felhasználhatja a .NET felhasználó által definiált függvényeinek egy részét vagy mindegyikét. Vegye figyelembe, hogy az U-SQL a .NET-keretrendszer használja, míg az Apache Sparkhoz készült .NET a .NET Core 3.1-es vagy újabb verzióján alapul.

A felhasználói U-SQL-operátorok (UDO-k) az U-SQL UDO modellt használják az operátor kódjának kibővített végrehajtásához. Így az UDR-eket újra kell írni a felhasználó által definiált függvényekbe, hogy illeszkedjenek a Spark végrehajtási modelljéhez.

Az Apache Sparkhoz készült .NET jelenleg nem támogatja a felhasználó által definiált összesítőket. Így az U-SQL felhasználó által definiált összesítőit a Scalában írt Spark felhasználó által definiált összesítőkké kell lefordítani.

Ha nem szeretné kihasználni az Apache Sparkhoz készült .NET képességeit, át kell írnia a kifejezéseket egy megfelelő Spark-, Scala-, Java- vagy Python-kifejezésre, függvényre, összesítőre vagy összekötőre.

Ha a U-SQL-szkriptekben nagy mennyiségű .NET-logika található, további útmutatásért forduljon hozzánk a Microsoft-fiók képviselőjén keresztül.

Az alábbi részletek a .NET- és C#-használati eseteket ismertetik az U-SQL-szkriptekben.

Skaláris beágyazott U-SQL C# kifejezések átalakítása

A U-SQL kifejezésnyelve C#. A skaláris beágyazott U-SQL-kifejezések közül sok natív módon van implementálva a jobb teljesítmény érdekében, míg az összetettebb kifejezések a .NET-keretrendszerbe való meghívással végrehajthatók.

A Spark saját skaláris kifejezési nyelvvel rendelkezik (akár a DSL részeként, akár a SparkSQL-ben), és lehetővé teszi a JVM, .NET vagy Python-futtatókörnyezethez írt, felhasználó által definiált függvények meghívását.

Ha skaláris kifejezésekkel rendelkezik az U-SQL-ben, először meg kell találnia a legmegfelelőbb natívan értelmezhető Spark skaláris kifejezést, hogy a lehető legjobb teljesítményt érje el, majd a többi kifejezést a választott Spark-futtatókörnyezet nyelvének felhasználó által definiált függvényére képezheti le.

Vegye figyelembe, hogy a .NET és a C# különböző típusú szemantikával rendelkezik, mint a JVM- és Python-futtatókörnyezetek, valamint a Spark DSL-jei. A típusrendszer-különbségekről az alábbiakban talál további információt.

Felhasználó által definiált skaláris .NET-függvények és felhasználó által definiált összesítők átalakítása

Az U-SQL lehetővé teszi tetszőleges skaláris .NET-függvények meghívását és a .NET-ben írt, felhasználó által definiált összesítők meghívását.

A Spark emellett támogatja a felhasználók által definiált függvényeket és a felhasználó által definiált összesítőket, amelyeket a legtöbb üzemeltetési nyelven írnak, amelyeket a Spark DSL-ből és SparkSQL-ből lehet meghívni.

Ahogy korábban említettük, az Apache Sparkhoz készült .NET támogatja a .NET-ben írt, felhasználó által definiált függvényeket, de nem támogatja a felhasználó által definiált összesítőket. Így a felhasználó által definiált függvények esetében az Apache Sparkhoz készült .NET használható, míg a felhasználó által definiált összesítőket a Sparkhoz készült Scalában kell létrehozni.

Felhasználó által definiált operátorok (UDR-ek) átalakítása

Az U-SQL a felhasználó által definiált operátorok (UDR-ek) számos kategóriáját biztosítja, például az elszívókat, a kimenetiket, a reduktorokat, a processzorokat, az appliereket és a kombinereket, amelyek .NET-ben (és - bizonyos mértékig - Pythonban és R-ben) írhatók.

A Spark nem ugyanazt a bővíthetőségi modellt kínálja az operátorok számára, de néhányhoz egyenértékű képességekkel rendelkezik.

Az elszívókkal és a kimenetikkel egyenértékű Spark-összekötők a Spark-összekötők. Számos U-SQL-kinyerő esetében a Spark-közösségben talál egy megfelelő összekötőt. Másoknak egyéni összekötőt kell írnia. Ha az U-SQL-kinyerő összetett, és több .NET-kódtárat használ, érdemes lehet olyan összekötőt létrehozni a Scalában, amely interop használatával hívja meg az adatok tényleges feldolgozását végrehajtó .NET-kódtárat. Ebben az esetben üzembe kell helyeznie a .NET Core-futtatókörnyezetet a Spark-fürtön, és meg kell győződnie arról, hogy a hivatkozott .NET-kódtárak megfelelnek a .NET Standard 2.0 szabványnak.

Az U-SQL UPO-k egyéb típusait felhasználó által definiált függvényekkel és összesítőkkel, valamint a szemantikailag megfelelő Spark DLS- vagy SparkSQL-kifejezéssel kell újraírni. Egy processzor például leképezhető a különböző UDF-hívásokat tartalmazó SELECT függvényre, amely egy adatkeretet argumentumként tartalmazó függvényként van csomagolva, és egy adatkeretet ad vissza.

A U-SQL választható kódtárainak átalakítása

Az U-SQL opcionális és demókódtárak készletét biztosítja, amelyek Python-, R-, JSON-, XML-, AVRO-támogatást és azure AI-szolgáltatások egyes funkcióit kínálják.

A Spark saját Python- és R-integrációt, valamint pySpark- és SparkR-integrációt kínál, és összekötőket biztosít jSON, XML és AVRO olvasásához és írásához.

Ha át kell alakítania egy, az Azure AI-szolgáltatáskódtárakra hivatkozó szkriptet, javasoljuk, hogy lépjen velünk kapcsolatba a Microsoft-fiók képviselőjén keresztül.

Típusértékek átalakítása

Mivel az U-SQL típusrendszere a .NET-típusrendszeren alapul, és a Spark saját típusrendszert használ, amelyre hatással van a gazdanyelvi kötés, meg kell győződnie arról, hogy a használt típusok közel vannak, és bizonyos típusok esetében a típustartományok, a pontosság és/vagy a skálázás kissé eltérő lehet. Emellett az U-SQL és a Spark másképp kezeli az null értékeket.

Adattípusok

Az alábbi táblázat a Spark, Scala és PySpark megfelelő típusait tartalmazza az adott U-SQL-típusokhoz.

U-SQL Spark Scala PySpark
byte
sbyte ByteType Byte ByteType
int IntegerType Int IntegerType
uint
long LongType Long LongType
ulong
float FloatType Float FloatType
double DoubleType Double DoubleType
decimal DecimalType java.math.BigDecimal DecimalType
short ShortType Short ShortType
ushort
char Char
string StringType String StringType
DateTime DateType, TimestampType java.sql.Date, java.sql.Timestamp DateType, TimestampType
bool BooleanType Boolean BooleanType
Guid
byte[] BinaryType Array[Byte] BinaryType
SQL.MAP<K,V> MapType(keyType, valueType, valueContainsNull) scala.collection.Map MapType(keyType, valueType, valueContainsNull=True)
SQL.ARRAY<T> ArrayType(elementType, containsNull) scala.collection.Seq ArrayType(elementType, containsNull=True)

További információkért lásd:

A NULL kezelése

A Sparkban az alapértelmezett típusok engedélyezik a NULL értékeket, míg az U-SQL-ben a skaláris, nem objektumos értékeket explicit módon null értékűként jelöli meg. Bár a Spark lehetővé teszi, hogy egy oszlopot nem null értékűként definiáljon, nem kényszeríti ki a kényszert, és helytelen eredményhez vezethet.

A Sparkban a NULL érték azt jelzi, hogy az érték ismeretlen. A Spark NULL értéke különbözik minden értéktől, beleértve önmagát is. Két Spark NULL érték, illetve egy NULL érték és bármely más érték összehasonlítása ismeretlen értéket ad vissza, mert az egyes NULL értékek értéke ismeretlen.

Ez a viselkedés különbözik az U-SQL-től, amely a C#-szemantikát követi, ahol null különbözik minden értéktől, de egyenlő önmagával.

Így egy SparkSQL-utasítás SELECT nulla WHERE column_name = NULL sort ad vissza, még akkor is, ha null értékek vannak a -ben column_name, míg az U-SQL-ben azokat a sorokat adja vissza, ahol column_name a értéke null. Hasonlóképpen, a WHERE column_name != NULL Spark-utasítás SELECT nulla sorokat ad vissza, még akkor is, ha nem null értékűek a rendszerbencolumn_name, míg az U-SQL-ben a nem null értékű sorokat adja vissza. Így ha az U-SQL null-ellenőrző szemantikáját szeretné használni, akkor az isnull és az isotnull (vagy azok DSL-ekvivalensét) kell használnia.

U-SQL-katalógusobjektumok átalakítása

Az egyik fő különbség az, hogy az U-SQL-szkriptek használhatják a katalógusobjektumokat, amelyek közül sok nem rendelkezik közvetlen Spark-megfelelővel.

A Spark támogatja a Hive-metatár fogalmait, elsősorban az adatbázisokat, táblákat és nézeteket, így U-SQL-adatbázisokat és -sémákat képezhet le Hive-adatbázisokra, U-SQL-táblákat Spark-táblákra (lásd: U-SQL-táblákban tárolt adatok áthelyezése), de nem támogatja a táblaértékű függvényeket (TVF-eket), a tárolt eljárásokat, az U-SQL-szerelvényeket, a külső adatforrásokat stb.

Az U-SQL-kódobjektumok, például nézetek, TVF-ek, tárolt eljárások és szerelvények a Spark kódfüggvényei és kódtárai segítségével modellezhetők, és a gazdanyelv függvényeivel és eljárási absztrakciós mechanizmusával (például Python-modulok importálásával vagy Scala-függvényekre való hivatkozással) hivatkozhatók.

Ha az U-SQL-katalógust az adatok és a kódobjektumok projektek és csapatok közötti megosztására használták, akkor egyenértékű megosztási mechanizmusokat kell használni (például a Maven-t a kódobjektumok megosztásához).

U-SQL-sorhalmaz-kifejezések és SQL-alapú skaláris kifejezések átalakítása

Az U-SQL alapvető nyelve a sorhalmazok átalakítása, és sql-alapú. Az alábbiakban az U-SQL-ben kínált leggyakoribb sorhalmaz-kifejezések nem kimerítő listája látható:

  • SELECT/FROM/WHERE/GROUP BY+Összesítések+HAVING/ORDER BY+FETCH

  • INNER/OUTER/CROSS/SEMIJOIN Kifejezések

  • CROSS/OUTERAPPLY Kifejezések

  • PIVOT/UNPIVOT Kifejezések

  • VALUES rowset konstruktor

  • Kifejezések beállítása UNION/OUTER UNION/INTERSECT/EXCEPT

Az U-SQL emellett különböző SQL-alapú skaláris kifejezéseket is biztosít, például

  • OVER ablakos kifejezések
  • különböző beépített összesítők és rangsorolási függvények (SUMFIRSTstb.)
  • Néhány ismerős SQL skaláris kifejezés: CASE, LIKE, (NOT) IN, ANDstb OR .

A Spark a legtöbb kifejezéshez DSL és SparkSQL formátumban is kínál egyenértékű kifejezéseket. A Sparkban natív módon nem támogatott kifejezések némelyikét újra kell írni a natív Spark-kifejezések és szemantikailag egyenértékű minták kombinációjával. Például az OUTER UNION előrejelzések és az egyesítések egyenértékű kombinációjára kell lefordítani.

A NULL értékek eltérő kezelése miatt az U-SQL-illesztés mindig megfelel egy sornak, ha mindkét összehasonlítandó oszlop NULL értéket tartalmaz, míg a Sparkban lévő illesztés csak akkor egyezik meg az ilyen oszlopokkal, ha explicit null-ellenőrzéseket ad hozzá.

Egyéb U-SQL-fogalmak átalakítása

Az U-SQL számos egyéb funkciót és fogalmat is kínál, például összevont lekérdezéseket SQL Server adatbázisokon, paramétereken, skaláris és lambda kifejezésváltozókon, rendszerváltozókon és OPTION tippeken.

Összevont lekérdezések SQL Server adatbázisokon/külső táblákon

Az U-SQL adatforrásokat és külső táblákat, valamint közvetlen lekérdezéseket biztosít Azure SQL Database-hez. Bár a Spark nem ugyanazokat az objektum-absztrakciókat kínálja, spark-összekötőt biztosít az SQL-adatbázisok lekérdezéséhez használható Azure SQL Database-hez.

U-SQL-paraméterek és -változók

A paraméterek és a felhasználói változók egyenértékű fogalmakkal rendelkeznek a Sparkban és azok üzemeltetési nyelveiben.

A Scalában például definiálhat egy változót a var kulcsszóval:

var x = 2 * 3;
println(x)

Az U-SQL rendszerváltozói (a változókkal @@kezdődő változók) két kategóriába sorolhatók:

  • Beállítható rendszerváltozók, amelyek meghatározott értékekre állíthatók be, hogy hatással legyenek a szkriptek viselkedésére
  • Információs rendszerváltozók, amelyek rendszer- és feladatszintű információkat kérdeznek le

A legtöbb beállítható rendszerváltozónak nincs közvetlen megfelelője a Sparkban. Az információs rendszer változóinak egy része modellezhető úgy, hogy argumentumként adja át az információkat a feladat végrehajtása során, másoknak pedig a Spark üzemeltetési nyelvében van egy egyenértékű függvénye.

U-SQL-tippek

Az U-SQL számos szintaktikai módszert kínál a lekérdezésoptimalizáló és a végrehajtási motor tippjeinek megadására:

  • U-SQL rendszerváltozó beállítása
  • a OPTION rowset kifejezéshez társított záradék, amely adatokat vagy tervmutatót ad meg
  • illesztésmutató az illesztés kifejezés szintaxisában (például BROADCASTLEFT: )

A Spark költségalapú lekérdezésoptimalizálója saját képességekkel rendelkezik, hogy tippeket nyújtson, és finomhangolja a lekérdezési teljesítményt. Tekintse meg a megfelelő dokumentációt.

Következő lépések