Informatie over Apache Spark-code voor U-SQL-ontwikkelaars
Belangrijk
Azure Data Lake Analytics is op 29 februari 2024 buiten gebruik gesteld. Meer informatie vindt u in deze aankondiging.
Voor gegevensanalyse kan uw organisatie Azure Synapse Analytics of Microsoft Fabric gebruiken.
Deze sectie bevat richtlijnen op hoog niveau voor het transformeren van U-SQL-scripts naar Apache Spark.
- Het begint met een vergelijking van de verwerkingsparadigma's van de twee talen
- Hier vindt u tips voor het volgende:
- Scripts transformeren, inclusief U-SQL-expressies voor rijensets
- .NET-code
- Data types
- Catalogusobjecten
Inzicht in de U-SQL- en Spark-taal en -verwerkingsparadigma's
Voordat u begint met het migreren van U-SQL-scripts van Azure Data Lake Analytics naar Spark, is het handig om de algemene taal te begrijpen en filosofieën van de twee systemen te verwerken.
U-SQL is een declaratieve querytaal die gebruikmaakt van een gegevensstroomparadigma en waarmee u eenvoudig gebruikerscode kunt insluiten en uitschalen die is geschreven in .NET (bijvoorbeeld C#), Python en R. De gebruikersextensies kunnen eenvoudige expressies of door de gebruiker gedefinieerde functies implementeren, maar kunnen de gebruiker ook de mogelijkheid bieden om zogenaamde door de gebruiker gedefinieerde operators te implementeren die aangepaste operators implementeren om transformaties op rijsetniveau, extracties en schrijfuitvoer uit te voeren.
Spark is een uitbreidbaar framework dat verschillende taalbindingen biedt in Scala, Java, Python, .NET enzovoort, waarbij u voornamelijk uw code in een van deze talen schrijft, gegevensabstracties maakt met de naam tolerante gedistribueerde gegevenssets (RDD), dataframes en gegevenssets en vervolgens een LINQ-achtige domeinspecifieke taal (DSL) gebruikt om ze te transformeren. Het biedt ook SparkSQL als een declaratieve subtaal voor de abstracties van het gegevensframe en de gegevensset. De DSL biedt twee categorieën bewerkingen, transformaties en acties. Het toepassen van transformaties op de gegevensabstracties voert de transformatie niet uit, maar bouwt in plaats daarvan het uitvoeringsplan op dat wordt ingediend voor evaluatie met een actie (bijvoorbeeld het schrijven van het resultaat in een tijdelijke tabel of bestand of het afdrukken van het resultaat).
Bij het vertalen van een U-SQL-script naar een Spark-programma moet u dus bepalen welke taal u wilt gebruiken om ten minste de abstractie van het gegevensframe te genereren (dit is momenteel de meest gebruikte gegevensabstractie) en of u de declaratieve gegevensstroomtransformaties wilt schrijven met behulp van de DSL of SparkSQL. In sommige complexere gevallen moet u uw U-SQL-script mogelijk splitsen in een reeks Spark en andere stappen die zijn geïmplementeerd met Azure Batch of Azure Functions.
Bovendien biedt Azure Data Lake Analytics U-SQL in een serverloze taakserviceomgeving waar resources worden toegewezen voor elke taak, terwijl Azure Synapse Spark, Azure Databricks en Azure HDInsight Spark Spark aanbieden in de vorm van een clusterservice of met zogenaamde Spark-poolsjablonen. Bij het transformeren van uw toepassing moet u rekening houden met de gevolgen van het maken, aanpassen, schalen en buiten gebruik stellen van de clusters of pools.
U-SQL-scripts transformeren
U-SQL-scripts volgen het volgende verwerkingspatroon:
- Gegevens worden gelezen uit ongestructureerde bestanden, met behulp van de
EXTRACT
instructie, een locatie- of bestandssetspecificatie, en de ingebouwde of door de gebruiker gedefinieerde extractor en het gewenste schema, of uit U-SQL-tabellen (beheerde of externe tabellen). Deze wordt weergegeven als een rijenset. - De rijensets worden getransformeerd in meerdere U-SQL-instructies die U-SQL-expressies toepassen op de rijensets en nieuwe rijensets produceren.
- Ten slotte worden de resulterende rijensets uitgevoerd in bestanden met behulp van de
OUTPUT
instructie waarmee de locatie(en) en een ingebouwde of door de gebruiker gedefinieerde uitvoerset worden opgegeven, of in een U-SQL-tabel.
Het script wordt lazily geëvalueerd, wat betekent dat elke extractie- en transformatiestap is samengesteld in een expressiestructuur en globaal wordt geëvalueerd (de gegevensstroom).
Spark-programma's zijn vergelijkbaar met het gebruik van Spark-connectors om de gegevens te lezen en de gegevensframes te maken, vervolgens de transformaties toe te passen op de dataframes met behulp van de LINQ-achtige DSL of SparkSQL, en vervolgens het resultaat te schrijven in bestanden, tijdelijke Spark-tabellen, sommige typen programmeertalen of de console.
.NET-code transformeren
De expressietaal van U-SQL is C# en biedt verschillende manieren om aangepaste .NET-code uit te schalen met door de gebruiker gedefinieerde functies, door de gebruiker gedefinieerde operators en door de gebruiker gedefinieerde aggregators.
Azure Synapse en Azure HDInsight Spark ondersteunen nu beide systeemeigen het uitvoeren van .NET-code met .NET voor Apache Spark. Dit betekent dat u mogelijk bepaalde of alle door de gebruiker gedefinieerde .NET-functies met Spark opnieuw kunt gebruiken. U-SQL maakt echter gebruik van .NET Framework terwijl .NET voor Apache Spark is gebaseerd op .NET Core 3.1 of hoger.
U-SQL door de gebruiker gedefinieerde operators (UDO's) gebruiken het U-SQL UDO-model om uitgeschaalde uitvoering van de code van de operator te bieden. UDF's moeten dus opnieuw worden geschreven in door de gebruiker gedefinieerde functies om in het Spark-uitvoeringsmodel te passen.
.NET voor Apache Spark biedt momenteel geen ondersteuning voor door de gebruiker gedefinieerde aggregators. Daarom moeten door de gebruiker gedefinieerde U-SQL-aggregators worden omgezet in door de gebruiker gedefinieerde Spark-aggregators die zijn geschreven in Scala.
Als u niet wilt profiteren van de mogelijkheden van .NET voor Apache Spark, moet u uw expressies herschrijven naar een equivalente Spark-, Scala-, Java- of Python-expressie, functie, aggregator of connector.
Als u in elk geval een grote hoeveelheid .NET-logica in uw U-SQL-scripts hebt, neemt u contact met ons op via uw Microsoft-accountvertegenwoordiger voor verdere begeleiding.
De volgende details zijn voor de verschillende gevallen van .NET- en C#-gebruik in U-SQL-scripts.
Scalaire inline U-SQL C#-expressies transformeren
De expressietaal van U-SQL is C#. Veel van de scalaire inline U-SQL-expressies worden systeemeigen geïmplementeerd voor verbeterde prestaties, terwijl complexere expressies kunnen worden uitgevoerd via het aanroepen van het .NET Framework.
Spark heeft een eigen scalaire expressietaal (ofwel als onderdeel van de DSL of in SparkSQL) en staat het aanroepen van door de gebruiker gedefinieerde functies toe die zijn geschreven voor de JVM-, .NET- of Python-runtime.
Als u scalaire expressies in U-SQL hebt, moet u eerst de meest geschikte, systeemeigen begrepen Scalaire Spark-expressie vinden om de meeste prestaties te krijgen en vervolgens de andere expressies toewijzen aan een door de gebruiker gedefinieerde functie van de Spark-runtimetaal van uw keuze.
Houd er rekening mee dat .NET en C# een ander type semantiek hebben dan de JVM- en Python-runtimes en de DSL van Spark. Zie hieronder voor meer informatie over de verschillen in het typesysteem.
Door de gebruiker gedefinieerde scalaire .NET-functies en door de gebruiker gedefinieerde aggregators transformeren
U-SQL biedt manieren om willekeurige scalaire .NET-functies aan te roepen en door de gebruiker gedefinieerde aggregators aan te roepen die zijn geschreven in .NET.
Spark biedt ook ondersteuning voor door de gebruiker gedefinieerde functies en door de gebruiker gedefinieerde aggregators die zijn geschreven in de meeste hostingtalen die kunnen worden aangeroepen vanuit Spark's DSL en SparkSQL.
Zoals hierboven vermeld, ondersteunt .NET voor Apache Spark door de gebruiker gedefinieerde functies die zijn geschreven in .NET, maar biedt geen ondersteuning voor door de gebruiker gedefinieerde aggregators. Voor door de gebruiker gedefinieerde functies kan .NET voor Apache Spark dus worden gebruikt, terwijl door de gebruiker gedefinieerde aggregators moeten worden gemaakt in Scala voor Spark.
Door de gebruiker gedefinieerde operators (UDF's) transformeren
U-SQL biedt verschillende categorieën door de gebruiker gedefinieerde operators (UDF's), zoals extractors, outputters, reducers, processors, appliers en combinaties die kunnen worden geschreven in .NET (en - in zekere mate - in Python en R).
Spark biedt niet hetzelfde uitbreidbaarheidsmodel voor operators, maar biedt vergelijkbare mogelijkheden voor sommige.
Spark-equivalent aan extractors en outputters is Spark-connectors. Voor veel U-SQL-extractors vindt u mogelijk een equivalente connector in de Spark-community. Voor anderen moet u een aangepaste connector schrijven. Als de U-SQL-extractor complex is en gebruikmaakt van verschillende .NET-bibliotheken, is het misschien beter om een connector in Scala te bouwen die interop gebruikt om de .NET-bibliotheek aan te roepen die de werkelijke verwerking van de gegevens uitvoert. In dat geval moet u de .NET Core-runtime implementeren in het Spark-cluster en ervoor zorgen dat de .NET-bibliotheken naar .NET Standard 2.0 voldoen.
De andere typen U-SQL UDOs moeten opnieuw worden geschreven met behulp van door de gebruiker gedefinieerde functies en aggregators en de semantisch geschikte Spark DLS- of SparkSQL-expressie. Een processor kan bijvoorbeeld worden toegewezen aan een SELECT van verschillende UDF-aanroepen, verpakt als een functie die een dataframe als argument gebruikt en een dataframe retourneert.
Optionele bibliotheken van U-SQL transformeren
U-SQL biedt een set optionele en demobibliotheken die Python, R, JSON, XML, AVRO-ondersteuning en enkele mogelijkheden van Azure AI-services bieden.
Spark biedt een eigen Python- en R-integratie, respectievelijk pySpark en SparkR, en biedt connectors voor het lezen en schrijven van JSON, XML en AVRO.
Als u een script wilt transformeren dat verwijst naar de Azure AI-servicesbibliotheken, raden we u aan contact met ons op te stellen via uw Microsoft-accountvertegenwoordiger.
Getypte waarden transformeren
Omdat het typesysteem van U-SQL is gebaseerd op het .NET-typesysteem en Spark een eigen typesysteem heeft dat wordt beïnvloed door de hosttaalbinding, moet u ervoor zorgen dat de typen waarop u werkt, dicht zijn en voor bepaalde typen kunnen de typebereiken, precisie en/of schaal enigszins verschillen. Bovendien behandelen null
U-SQL en Spark waarden anders.
Data types
De volgende tabel bevat de equivalente typen in Spark, Scala en PySpark voor de opgegeven U-SQL-typen.
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) |
Zie voor meer informatie:
Behandeling van NULL
In Spark staan typen per standaard NULL-waarden toe terwijl u in U-SQL expliciet scalaire, niet-object als null-waarde markeert. Hoewel u met Spark een kolom kunt definiëren als niet nullable, wordt de beperking niet afgedwongen en kan dit leiden tot een onjuist resultaat.
In Spark geeft NULL aan dat de waarde onbekend is. Een Spark NULL-waarde verschilt van elke waarde, inclusief zichzelf. Vergelijkingen tussen twee Spark NULL-waarden, of tussen een NULL-waarde en een andere waarde, retourneren onbekend omdat de waarde van elke NULL onbekend is.
Dit gedrag verschilt van U-SQL, die C#-semantiek volgt, waarbij null
elke waarde verschilt, maar gelijk is aan zichzelf.
Een SparkSQL-instructie SELECT
die gebruikmaakt WHERE column_name = NULL
van retourneert dus nul rijen, zelfs als er NULL-waarden zijn, column_name
terwijl in U-SQL de rijen worden geretourneerd waarop column_name
is ingesteld null
. Op dezelfde manier retourneert een Spark-instructie SELECT
die gebruikmaakt WHERE column_name != NULL
van nul rijen, zelfs als er niet-null-waarden zijn column_name
, terwijl in U-SQL de rijen worden geretourneerd die niet null zijn. Dus als u de U-SQL null-check-semantiek wilt, moet u isnull en isnotnull gebruiken (of hun DSL-equivalent).
U-SQL-catalogusobjecten transformeren
Een belangrijk verschil is dat U-SQL-scripts gebruik kunnen maken van de catalogusobjecten, waarvan veel geen directe Spark-equivalent hebben.
Spark biedt wel ondersteuning voor de Hive Meta Store-concepten, voornamelijk databases, tabellen en weergaven, zodat u U-SQL-databases en -schema's kunt toewijzen aan Hive-databases en U-SQL-tabellen aan Spark-tabellen (zie Gegevens verplaatsen die zijn opgeslagen in U-SQL-tabellen), maar het biedt geen ondersteuning voor tabelwaardefuncties (TVF's), opgeslagen procedures, U-SQL-assembly's, externe gegevensbronnen, enzovoort.
De U-SQL-codeobjecten, zoals weergaven, TVF's, opgeslagen procedures en assembly's, kunnen worden gemodelleerd via codefuncties en bibliotheken in Spark en waarnaar wordt verwezen met behulp van de functie van de hosttaal en procedurele abstractiemechanismen (bijvoorbeeld door Python-modules te importeren of te verwijzen naar Scala-functies).
Als de U-SQL-catalogus is gebruikt voor het delen van gegevens en codeobjecten in projecten en teams, moeten equivalente mechanismen voor delen worden gebruikt (bijvoorbeeld Maven voor het delen van codeobjecten).
U-SQL-rijsetexpressies en scalaire expressies op basis van SQL transformeren
De kerntaal van U-SQL transformeert rijensets en is gebaseerd op SQL. Hier volgt een niet-bestaande lijst met de meest voorkomende rowset-expressies die worden aangeboden in U-SQL:
SELECT
/FROM
/WHERE
/GROUP BY
+Aggregates+HAVING
/ORDER BY
+FETCH
INNER
/OUTER
/CROSS
/SEMI
JOIN
uitdrukkingenCROSS
/OUTER
APPLY
uitdrukkingenPIVOT
/UNPIVOT
uitdrukkingenVALUES
rijsetconstructorExpressies instellen
UNION
/OUTER UNION
/INTERSECT
/EXCEPT
Daarnaast biedt U-SQL verschillende scalaire expressies op basis van SQL, zoals
OVER
vensterexpressies- diverse ingebouwde aggregators en classificatiefuncties (
SUM
,FIRST
enz.) - Enkele van de meest bekende SCALAire SQL-expressies:
CASE
, (NOT
LIKE
)IN
,AND
enzovoortOR
.
Spark biedt equivalente expressies in zowel de DSL- als sparkSQL-vorm voor de meeste van deze expressies. Sommige expressies die niet systeemeigen worden ondersteund in Spark, moeten opnieuw worden geschreven met behulp van een combinatie van de systeemeigen Spark-expressies en semantisch equivalente patronen. Dit moet bijvoorbeeld OUTER UNION
worden vertaald in de equivalente combinatie van projecties en samenvoegingen.
Vanwege de verschillende verwerking van NULL-waarden komt een U-SQL-join altijd overeen met een rij als beide kolommen die worden vergeleken een NULL-waarde bevatten, terwijl een join in Spark niet overeenkomt met dergelijke kolommen, tenzij expliciete null-controles worden toegevoegd.
Andere U-SQL-concepten transformeren
U-SQL biedt ook verschillende andere functies en concepten, zoals federatieve query's voor SQL Server-databases, parameters, scalaire en lambda-expressievariabelen, systeemvariabelen, OPTION
hints.
Federatieve query's voor SQL Server-databases/externe tabellen
U-SQL biedt gegevensbron en externe tabellen, evenals directe query's voor Azure SQL Database. Hoewel Spark niet dezelfde objectabstracties biedt, biedt spark-connector voor Azure SQL Database die kan worden gebruikt om query's uit te voeren op SQL-databases.
U-SQL-parameters en -variabelen
Parameters en gebruikersvariabelen hebben gelijkwaardige concepten in Spark en de bijbehorende hostingtalen.
In Scala kunt u bijvoorbeeld een variabele definiëren met het var
trefwoord:
var x = 2 * 3;
println(x)
U-SQL's systeemvariabelen (variabelen die beginnen met @@
) kunnen worden gesplitst in twee categorieën:
- Stel systeemvariabelen in die kunnen worden ingesteld op specifieke waarden om het gedrag van scripts te beïnvloeden
- Informatiesysteemvariabelen die informatie op systeem- en taakniveau invragen
De meeste ingestelde systeemvariabelen hebben geen direct equivalent in Spark. Sommige van de informatieve systeemvariabelen kunnen worden gemodelleerd door de informatie door te geven als argumenten tijdens het uitvoeren van de taak. Andere hebben mogelijk een equivalente functie in de hostingtaal van Spark.
U-SQL-hints
U-SQL biedt verschillende syntactische manieren om hints te bieden aan de queryoptimalisatie- en uitvoeringsengine:
- Een U-SQL-systeemvariabele instellen
- een
OPTION
component die is gekoppeld aan de rowset-expressie om een gegevens- of planhint te bieden - een joinhint in de syntaxis van de join-expressie (bijvoorbeeld
BROADCASTLEFT
)
De optimalisatiefunctie voor kostengebaseerde query's van Spark heeft zijn eigen mogelijkheden om hints te bieden en de queryprestaties af te stemmen. Raadpleeg de bijbehorende documentatie.
Volgende stappen
- Informatie over Spark-gegevensindelingen voor U-SQL-ontwikkelaars
- .NET voor Apache Spark
- Uw big data analytics-oplossingen upgraden van Azure Data Lake Storage Gen1 naar Azure Data Lake Storage Gen2
- Gegevens transformeren met spark-activiteit in Azure Data Factory
- Gegevens transformeren met behulp van Hadoop Hive-activiteit in Azure Data Factory
- Wat is Apache Spark in Azure HDInsight