Vysvětlení kódu Apache Sparku pro vývojáře U-SQL

Důležité

Azure Data Lake Analytics vyřazena 29. února 2024. Další informace najdete v tomto oznámení.

K analýze dat může vaše organizace použít Azure Synapse Analytics nebo Microsoft Fabric.

Tato část obsahuje základní pokyny k transformaci skriptů U-SQL na Apache Spark.

Vysvětlení paradigmat jazyka U-SQL a Sparku a jejich zpracování

Než začnete migrovat skripty U-SQL azure Data Lake Analytics do Sparku, je užitečné porozumět obecnému jazyku a filozofii zpracování těchto dvou systémů.

U-SQL je deklarativní dotazovací jazyk podobný JAZYKu SQL, který používá paradigma toku dat a umožňuje snadno vkládat a škálovat uživatelský kód napsaný v .NET (například C#), Pythonu a R. Uživatelská rozšíření mohou implementovat jednoduché výrazy nebo uživatelem definované funkce, ale mohou také uživateli poskytnout možnost implementovat tzv. uživatelem definované operátory, které implementují vlastní operátory pro provádění transformací, extrakcí a zápisu výstupu na úrovni sady řádků.

Spark je architektura se škálováním na více systémů, která nabízí několik jazykových vazeb v jazyce Scala, Java, Python, .NET atd., kde primárně píšete kód v jednom z těchto jazyků, vytváříte abstrakce dat označované jako odolné distribuované datové sady (RDD), datové rámce a datové sady a pak je transformujete pomocí jazyka LINQ (DSL). Poskytuje také SparkSQL jako deklarativní dílčí jazyk pro datový rámec a abstrakce datové sady. Dsl poskytuje dvě kategorie operací, transformací a akcí. Použitím transformací na abstrakce dat se neprovedou transformace, ale místo toho sestaví plán provádění, který se odešle k vyhodnocení pomocí akce (například zápis výsledku do dočasné tabulky nebo souboru nebo tisk výsledku).

Proto při překladu skriptu U-SQL do programu Spark se budete muset rozhodnout, který jazyk chcete použít, abyste alespoň vygenerovali abstrakci datového rámce (což je aktuálně nejčastěji používaná abstrakce dat) a jestli chcete zapisovat transformace deklarativního toku dat pomocí DSL nebo SparkSQL. V některých složitějších případech může být potřeba rozdělit skript U-SQL do posloupnosti Sparku a dalších kroků implementovaných pomocí Azure Batch nebo Azure Functions.

Azure Data Lake Analytics navíc nabízí U-SQL v bezserverovém prostředí služby úloh, kde se prostředky přidělují pro každou úlohu, zatímco Azure Synapse Spark, Azure Databricks a Azure HDInsight nabízejí Spark buď ve formě clusterové služby, nebo pomocí takzvaných šablon fondů Spark. Při transformaci aplikace budete muset vzít v úvahu důsledky vytváření, nastavování velikosti, škálování a vyřazení clusterů nebo fondů z provozu.

Transformace skriptů U-SQL

Skripty U-SQL se řídí následujícím vzorem zpracování:

  1. Data se čtou z nestrukturovaných souborů pomocí EXTRACT příkazu , specifikace umístění nebo sady souborů a integrovaného nebo uživatelem definovaného extraktoru a požadovaného schématu nebo z tabulek U-SQL (spravovaných nebo externích tabulek). Je reprezentovaná jako sada řádků.
  2. Sady řádků se transformují ve více příkazech U-SQL, které aplikují výrazy U-SQL na sady řádků a vytvářejí nové sady řádků.
  3. Výsledné sady řádků se nakonec vydají do souborů pomocí OUTPUT příkazu , který určuje umístění a předdefinovaný nebo uživatelem definovaný výstupní modul, nebo do tabulky U-SQL.

Skript se vyhodnocuje líně, což znamená, že každý krok extrakce a transformace se skládá do stromu výrazů a globálně se vyhodnotí (tok dat).

Programy Spark jsou podobné v tom, že byste použili konektory Spark ke čtení dat a vytvoření datových rámců, pak transformace v datových rámcích použili pomocí technologie DSL podobné LINQ nebo SparkSQL a výsledek zapište do souborů, dočasných tabulek Sparku, některých typů programovacích jazyků nebo konzoly.

Transformace kódu .NET

Jazyk výrazů U-SQL je jazyk C# a nabízí různé způsoby horizontálního navýšení kapacity vlastního kódu .NET pomocí uživatelem definovaných funkcí, operátorů definovaných uživatelem a agregátorů definovaných uživatelem.

Azure Synapse i Azure HDInsight Spark teď nativně podporují spouštění kódu .NET pomocí .NET pro Apache Spark. To znamená, že se Sparkem můžete potenciálně znovu použít některé nebo všechny uživatelem definované funkce .NET. Mějte ale na paměti, že U-SQL používá rozhraní .NET Framework, zatímco .NET pro Apache Spark je založené na .NET Core 3.1 nebo novějším.

Uživatelem definované operátory U-SQL používají model U-SQL UDO k zajištění provádění kódu operátoru se škálováním na více instancí. Proto se trasy definované uživatelem budou muset přepsat na uživatelem definované funkce, aby se vešly do modelu spouštění Sparku.

.NET pro Apache Spark v současné době nepodporuje uživatelem definované agregátory. Uživatelem definované agregátory U-SQL se proto budou muset přeložit na uživatelem definované agregátory Sparku napsané v jazyce Scala.

Pokud nechcete využívat funkce .NET pro Apache Spark, budete muset přepsat výrazy na ekvivalentní výraz Spark, Scala, Javu nebo Python, funkci, agregátor nebo konektor.

Pokud máte ve skriptech U-SQL velké množství logiky .NET, kontaktujte nás s žádostí o další pokyny prostřednictvím zástupce microsoftu pro zákazníky.

Následující podrobnosti se vztahují k různým případům použití rozhraní .NET a C# ve skriptech U-SQL.

Transformace skalárních vložených výrazů U-SQL C#

Jazyk výrazů U-SQL je C#. Mnoho skalárních vložených výrazů U-SQL je implementováno nativně, aby se zlepšil výkon, zatímco složitější výrazy by se mohly spouštět voláním rozhraní .NET Framework.

Spark má vlastní jazyk skalárních výrazů (buď jako součást DSL, nebo ve SparkSQL) a umožňuje volání uživatelem definovaných funkcí napsaných pro modul runtime JVM, .NET nebo Python.

Pokud máte v U-SQL skalární výrazy, měli byste nejprve najít nejvhodnější nativně pochopený skalární výraz Sparku, abyste získali nejvyšší výkon, a pak namapovat ostatní výrazy na uživatelem definovanou funkci libovolného jazyka sparkového modulu runtime.

Mějte na paměti, že .NET a C# mají jinou sémantiku typu než moduly runtime JVM a Python a dsl Sparku. Další podrobnosti o rozdílech mezi typem systému najdete níže .

Transformace uživatelem definovaných skalárních funkcí .NET a uživatelem definovaných agregátorů

U-SQL nabízí způsoby, jak volat libovolné skalární funkce .NET a volat uživatelem definované agregátory napsané v .NET.

Spark také nabízí podporu uživatelem definovaných funkcí a uživatelem definovaných agregátorů napsaných ve většině hostitelských jazyků, které je možné volat ze Sparku DSL a SparkSQL.

Jak je uvedeno výše, .NET pro Apache Spark podporuje uživatelem definované funkce napsané v .NET, ale nepodporuje uživatelem definované agregátory. Pro uživatelem definované funkce je tedy možné použít .NET pro Apache Spark, zatímco uživatelem definované agregátory musí být vytvořené v jazyce Scala pro Spark.

Transformace uživatelem definovaných operátorů (UPO)

U-SQL poskytuje několik kategorií uživatelem definovaných operátorů (UPO), jako jsou extraktory, výstupní moduly, reduktory, procesory, aplikační nástroje a kombinátory, které lze psát v .NET (a do určité míry i v Pythonu a R).

Spark nenabízí stejný model rozšiřitelnosti pro operátory, ale pro některé má ekvivalentní funkce.

Ekvivalentem Sparku k extraktorům a výstupům jsou konektory Sparku. Pro mnoho extraktorů U-SQL můžete najít ekvivalentní konektor v komunitě Spark. Pro ostatní budete muset napsat vlastní konektor. Pokud je extraktor U-SQL složitý a využívá několik knihoven .NET, může být vhodnější vytvořit konektor v jazyce Scala, který používá interop k volání knihovny .NET, která provádí skutečné zpracování dat. V takovém případě budete muset nasadit modul runtime .NET Core do clusteru Spark a ujistit se, že odkazované knihovny .NET vyhovují standardu .NET Standard 2.0.

Ostatní typy UDO U-SQL bude potřeba přepsat pomocí uživatelem definovaných funkcí a agregátorů a sémanticky vhodných výrazů Spark DLS nebo SparkSQL. Procesor může být například namapován na volání SELECT různých funkcí UDF zabalených jako funkce, která přebírá datový rámec jako argument a vrací datový rámec.

Transformace volitelných knihoven U-SQL

U-SQL poskytuje sadu volitelných a ukázkových knihoven, které nabízejí podporu Pythonu, R, JSON, XML, AVRO a některé možnosti služeb Azure AI.

Spark nabízí vlastní integraci Pythonu a R, pySpark a SparkR a poskytuje konektory pro čtení a zápis JSON, XML a AVRO.

Pokud potřebujete transformovat skript odkazující na knihovny služeb Azure AI, doporučujeme nás kontaktovat prostřednictvím zástupce microsoftu pro zákazníky.

Transformovat hodnoty typu

Vzhledem k tomu, že systém typů U-SQL je založený na systému typů .NET a Spark má vlastní systém typů, na který má vliv vazba jazyka hostitele, budete muset zajistit, aby typy, se kterými pracujete, byly blízko a pro určité typy, rozsahy typů, přesnost nebo škálování se můžou mírně lišit. Kromě toho U-SQL a Spark pracují s null hodnotami odlišně.

Typy dat

Následující tabulka obsahuje ekvivalentní typy Spark, Scala a PySpark pro dané typy U-SQL.

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)

Další informace naleznete v tématu:

Zacházení s hodnotou NULL

Ve Sparku typy ve výchozím nastavení povolují hodnoty NULL, zatímco v U-SQL explicitně označíte skalární objekt bez objektu s možnou hodnotou null. Spark sice umožňuje definovat sloupec jako sloupec s možnou hodnotou null, ale nevynutí omezení a může vést k nesprávnému výsledku.

Hodnota NULL ve Sparku označuje, že hodnota je neznámá. Hodnota Spark NULL se liší od jakékoli hodnoty, včetně sebe sama. Porovnání mezi dvěma hodnotami Spark NULL nebo mezi hodnotou NULL a jakoukoli jinou hodnotou vrátí neznámé, protože hodnota každé hodnoty NULL je neznámá.

Toto chování se liší od U-SQL, které následuje po sémantice jazyka C#, kde null se liší od jakékoli hodnoty, ale rovná se sama sobě.

Proto příkaz SparkSQL SELECT , který používá WHERE column_name = NULL , vrací nula řádků, i když v souboru existují hodnoty NULL, zatímco v column_nameU-SQL by vrátil řádky, kde column_name je nastavená na nullhodnotu . Podobně příkaz Spark SELECT , který používá WHERE column_name != NULL , vrací nula řádků i v případě, že v objektu nejsou hodnoty null, zatímco v column_nameU-SQL by vrátil řádky, které nemají hodnotu null. Pokud tedy chcete použít sémantiku kontroly hodnoty null U-SQL, měli byste použít isnull a isnotnull (nebo jejich ekvivalent DSL).

Transformace objektů katalogu U-SQL

Jedním z hlavních rozdílů je, že skripty U-SQL můžou využívat objekty katalogu, z nichž mnohé nemají žádný přímý ekvivalent Sparku.

Spark poskytuje podporu konceptů meta storu Hive, zejména databází, tabulek a zobrazení, takže můžete mapovat databáze a schémata U-SQL na databáze Hive a tabulky U-SQL na tabulky Sparku (viz Přesun dat uložených v tabulkách U-SQL), ale nepodporuje funkce vracející tabulky (TVF), uložené procedury, sestavení U-SQL, externí zdroje dat atd.

Objekty kódu U-SQL, jako jsou zobrazení, soubory TVF, uložené procedury a sestavení, lze modelovat prostřednictvím funkcí kódu a knihoven ve Sparku a odkazovat na je pomocí funkcí jazyka hostitele a mechanismů procedurální abstrakce (například importem modulů Pythonu nebo odkazováním na funkce Scala).

Pokud se katalog U-SQL používá ke sdílení dat a objektů kódu mezi projekty a týmy, je potřeba použít ekvivalentní mechanismy pro sdílení (například Maven pro sdílení objektů kódu).

Transformace výrazů sady řádků U-SQL a skalárních výrazů založených na SQL

Základní jazyk U-SQL transformuje sady řádků a je založený na SQL. Následuje nevyčerpatný seznam nejběžnějších výrazů sady řádků nabízených v U-SQL:

  • SELECT/FROM/WHERE/GROUP BY+Agregace+HAVING/ORDER BY+FETCH

  • INNER/OUTER/CROSS/SEMIJOIN Výrazy

  • CROSS/OUTERAPPLY Výrazy

  • PIVOT/UNPIVOT Výrazy

  • VALUES konstruktor sady řádků

  • Nastavení výrazů UNION/OUTER UNION/INTERSECT/EXCEPT

Kromě toho U-SQL poskytuje různé skalární výrazy založené na JAZYCE SQL, například

  • OVER výrazy oken
  • různé předdefinované agregátory a funkce řazení (SUMFIRSTatd.)
  • Některé z nejznámějších skalárních výrazů SQL: CASE, LIKE, (NOT) IN, ANDatd OR .

Spark nabízí ekvivalentní výrazy ve formě DSL i SparkSQL pro většinu těchto výrazů. Některé výrazy, které spark nepodporuje nativně, bude nutné přepsat pomocí kombinace nativních výrazů Sparku a sémanticky ekvivalentních vzorů. OUTER UNION Například se bude muset přeložit do ekvivalentní kombinace projekcí a sjednocení.

Vzhledem k odlišnému zpracování hodnot NULL bude spojení U-SQL vždy odpovídat řádku, pokud oba porovnávané sloupce obsahují hodnotu NULL, zatímco spojení ve Sparku nebude odpovídat těmto sloupcům, pokud nejsou přidány explicitní kontroly null.

Transformace dalších konceptů U-SQL

U-SQL také nabízí různé další funkce a koncepty, jako jsou federované dotazy na databáze SQL Server, parametry, skalární a lambda proměnné výrazů, systémové proměnné a OPTION nápovědy.

Federované dotazy na databáze SQL Server nebo externí tabulky

U-SQL poskytuje zdroj dat a externí tabulky a také přímé dotazy na Azure SQL Database. Spark sice nenabízí stejné abstrakce objektů, ale poskytuje konektor Spark pro Azure SQL Database, který se dá použít k dotazování databází SQL.

Parametry a proměnné U-SQL

Parametry a uživatelské proměnné mají ekvivalentní koncepty ve Sparku a jejich hostitelských jazycích.

Například v jazyce Scala můžete definovat proměnnou pomocí klíčového var slova:

var x = 2 * 3;
println(x)

Systémové proměnné U-SQL (proměnné začínající @@na ) lze rozdělit do dvou kategorií:

  • Nastavitelné systémové proměnné, které lze nastavit na konkrétní hodnoty, které mají vliv na chování skriptů
  • Proměnné informačního systému, které žadují informace na úrovni systému a úlohy

Většina nastavených systémových proměnných nemá ve Sparku žádný přímý ekvivalent. Některé proměnné informačního systému lze modelovat předáním informací jako argumentů během provádění úlohy, jiné můžou mít ekvivalentní funkci v hostitelském jazyce Sparku.

Nápovědy pro U-SQL

U-SQL nabízí několik syntaktických způsobů, jak poskytnout rady optimalizátoru dotazů a spouštěcímu modulu:

  • Nastavení systémové proměnné U-SQL
  • klauzule přidružená OPTION k výrazu sady řádků za účelem poskytnutí nápovědy k datům nebo plánu
  • tip spojení v syntaxi výrazu join (například BROADCASTLEFT)

Optimalizátor dotazů založený na nákladech sparku má vlastní funkce pro poskytování nápovědy a ladění výkonu dotazů. Projděte si odpovídající dokumentaci.

Další kroky