Informazioni sul codice Apache Spark per sviluppatori U-SQL

Importante

Azure Data Lake Analytics ritirato il 29 febbraio 2024. Per altre informazioni , vedere questo annuncio.

Per l'analisi dei dati, l'organizzazione può usare Azure Synapse Analytics o Microsoft Fabric.

Questa sezione fornisce indicazioni generali sulla trasformazione degli script U-SQL in Apache Spark.

Comprendere i paradigmi di elaborazione e linguaggio U-SQL e Spark

Prima di iniziare la migrazione degli script U-SQL di Azure Data Lake Analytics a Spark, è utile comprendere il linguaggio generale e le filosofie di elaborazione dei due sistemi.

U-SQL è un linguaggio di query dichiarativo simile a SQL che usa un paradigma del flusso di dati e consente di incorporare e scalare facilmente il codice utente scritto in .NET (ad esempio C#), Python e R. Le estensioni utente possono implementare espressioni semplici o funzioni definite dall'utente, ma possono anche offrire all'utente la possibilità di implementare i cosiddetti operatori definiti dall'utente che implementano operatori personalizzati per eseguire trasformazioni a livello di set di righe, estrazione e scrittura dell'output.

Spark è un framework con scalabilità orizzontale che offre diversi binding di linguaggio in Scala, Java, Python, .NET e così via, in cui si scrive principalmente il codice in uno di questi linguaggi, creare astrazioni dei dati denominate set di dati distribuiti resilienti (RDD), dataframe e set di dati e quindi usare un linguaggio SPECIFICO del dominio (DSL) simile a LINQ per trasformarli. Fornisce anche SparkSQL come sottolanguage dichiarativo nel dataframe e nelle astrazioni dei set di dati. Il linguaggio DSL fornisce due categorie di operazioni, trasformazioni e azioni. L'applicazione di trasformazioni alle astrazioni di dati non eseguirà la trasformazione, ma compilerà invece il piano di esecuzione che verrà inviato per la valutazione con un'azione , ad esempio scrivendo il risultato in una tabella o in un file temporaneo o stampando il risultato.

Pertanto, quando si traduce uno script U-SQL in un programma Spark, è necessario decidere quale linguaggio si vuole usare per generare almeno l'astrazione del frame di dati (che è attualmente l'astrazione dei dati usata più di frequente) e se si desidera scrivere le trasformazioni del flusso di dati dichiarativo usando DSL o SparkSQL. In alcuni casi più complessi potrebbe essere necessario suddividere lo script U-SQL in una sequenza di Spark e altri passaggi implementati con Azure Batch o Funzioni di Azure.

Azure Data Lake Analytics offre anche U-SQL in un ambiente del servizio processi serverless in cui le risorse vengono allocate per ogni processo, mentre Azure Synapse Spark, Azure Databricks e Azure HDInsight offrono Spark sotto forma di servizio cluster o con i cosiddetti modelli di pool spark. Quando si trasforma l'applicazione, è necessario tenere conto delle implicazioni di creazione, ridimensionamento, ridimensionamento e rimozione delle autorizzazioni per i cluster o i pool.

Trasformare gli script U-SQL

Gli script U-SQL seguono il modello di elaborazione seguente:

  1. I dati vengono letti da file non strutturati, usando l'istruzione EXTRACT , una specifica del percorso o del set di file e l'estrattore predefinito o definito dall'utente e lo schema desiderato oppure da tabelle U-SQL (tabelle gestite o esterne). È rappresentato come un set di righe.
  2. I set di righe vengono trasformati in più istruzioni U-SQL che applicano espressioni U-SQL ai set di righe e producono nuovi set di righe.
  3. Infine, i set di righe risultanti vengono restituiti in file usando l'istruzione OUTPUT che specifica i percorsi e un outputter predefinito o definito dall'utente o in una tabella U-SQL.

Lo script viene valutato in modo differito, ovvero ogni passaggio di estrazione e trasformazione è composto in un albero delle espressioni e valutato a livello globale (il flusso di dati).

I programmi Spark sono simili in quanto si usano i connettori Spark per leggere i dati e creare i dataframe, quindi applicare le trasformazioni nei dataframe usando IL LINGUAGGIO LINQ o SparkSQL, quindi scrivere il risultato in file, tabelle Spark temporanee, alcuni tipi di linguaggi di programmazione o la console.

Trasformare il codice .NET

Il linguaggio delle espressioni di U-SQL è C# e offre diversi modi per aumentare il numero di istanze di codice .NET personalizzato con funzioni definite dall'utente, operatori definiti dall'utente e aggregatori definiti dall'utente.

Azure Synapse e Azure HDInsight Spark supportano ora in modo nativo l'esecuzione di codice .NET con .NET per Apache Spark. Ciò significa che è possibile riutilizzare alcune o tutte le funzioni definite dall'utente .NET con Spark. Si noti tuttavia che U-SQL usa .NET Framework mentre .NET per Apache Spark è basato su .NET Core 3.1 o versione successiva.

Gli operatori U-SQL definiti dall'utente usano il modello U-SQL UDO per fornire l'esecuzione con scalabilità orizzontale del codice dell'operatore. Pertanto, gli UDO dovranno essere riscritti nelle funzioni definite dall'utente per adattarsi al modello di esecuzione spark.

.NET per Apache Spark attualmente non supporta aggregatori definiti dall'utente. Di conseguenza, gli aggregatori definiti dall'utente U-SQL dovranno essere convertiti in aggregatori definiti dall'utente Spark scritti in Scala.

Se non si vuole sfruttare le funzionalità di .NET per Apache Spark, è necessario riscrivere le espressioni in un'espressione Spark, Scala, Java o Python equivalente, funzione, aggregatore o connettore.

In ogni caso, se si dispone di una grande quantità di logica .NET negli script U-SQL, contattare Microsoft tramite il rappresentante dell'account Microsoft per altre indicazioni.

I dettagli seguenti sono relativi ai diversi casi di utilizzo di .NET e C# negli script U-SQL.

Trasformare espressioni C# scalari inline U-SQL

Il linguaggio delle espressioni di U-SQL è C#. Molte delle espressioni scalari inline U-SQL vengono implementate in modo nativo per migliorare le prestazioni, mentre è possibile eseguire espressioni più complesse tramite la chiamata a .NET Framework.

Spark ha un proprio linguaggio di espressione scalare (come parte del linguaggio DSL o in SparkSQL) e consente di chiamare in funzioni definite dall'utente scritte per il runtime JVM, .NET o Python.

Se si dispone di espressioni scalari in U-SQL, è prima necessario trovare l'espressione scalare Spark più appropriata per ottenere il massimo dalle prestazioni e quindi eseguire il mapping delle altre espressioni in una funzione definita dall'utente del linguaggio di runtime Spark di propria scelta.

Tenere presente che .NET e C# hanno una semantica di tipo diversa rispetto ai runtime JVM e Python e al linguaggio DSL di Spark. Per altri dettagli sulle differenze di sistema dei tipi, vedere di seguito .

Trasformare funzioni .NET scalari definite dall'utente e aggregatori definiti dall'utente

U-SQL consente di chiamare funzioni .NET scalari arbitrarie e di chiamare aggregatori definiti dall'utente scritti in .NET.

Spark offre anche il supporto per funzioni definite dall'utente e aggregatori definiti dall'utente scritti nella maggior parte dei linguaggi di hosting che possono essere chiamati dal linguaggio DSL e SparkSQL di Spark.

Come accennato in precedenza, .NET per Apache Spark supporta funzioni definite dall'utente scritte in .NET, ma non supporta gli aggregatori definiti dall'utente. Per le funzioni definite dall'utente, è quindi possibile usare .NET per Apache Spark, mentre gli aggregatori definiti dall'utente devono essere creati in Scala per Spark.

Trasformare gli operatori definiti dall'utente (UDO)

U-SQL offre diverse categorie di operatori definiti dall'utente(UDO), ad esempio estrattori, outputter, riduttori, processori, applicazioni e combinatori che possono essere scritti in .NET (e, in qualche misura, in Python e R).

Spark non offre lo stesso modello di estendibilità per gli operatori, ma ha funzionalità equivalenti per alcuni.

Spark equivalente agli estrattori e agli outputter è costituito dai connettori Spark. Per molti estrattori U-SQL, è possibile trovare un connettore equivalente nella community di Spark. Per altri, sarà necessario scrivere un connettore personalizzato. Se l'estrattore U-SQL è complesso e usa diverse librerie .NET, può essere preferibile compilare un connettore in Scala che usa l'interoperabilità per chiamare nella libreria .NET che esegue l'elaborazione effettiva dei dati. In questo caso, sarà necessario distribuire il runtime .NET Core nel cluster Spark e assicurarsi che le librerie .NET a cui si fa riferimento siano conformi a .NET Standard 2.0.

Gli altri tipi di U-SQL UDO dovranno essere riscritti usando funzioni e aggregatori definiti dall'utente e l'espressione SPARK DLS o SparkSQL appropriata semanticamente. Ad esempio, un processore può essere mappato a un select di varie chiamate definite dall'utente, in pacchetto come funzione che accetta un dataframe come argomento e restituisce un frame di dati.

Trasformare le librerie facoltative di U-SQL

U-SQL offre un set di librerie facoltative e demo che offrono python, R, JSON, XML, supporto AVRO e alcune funzionalità dei servizi di intelligenza artificiale di Azure.

Spark offre rispettivamente la propria integrazione di Python e R, pySpark e SparkR e offre connettori per leggere e scrivere JSON, XML e AVRO.

Se è necessario trasformare uno script che fa riferimento alle librerie dei servizi di intelligenza artificiale di Azure, è consigliabile contattare Microsoft tramite il rappresentante dell'account Microsoft.

Trasformare i valori tipizzati

Poiché il sistema di tipi di U-SQL è basato sul sistema dei tipi .NET e Spark ha un proprio sistema di tipi interessato dall'associazione del linguaggio host, è necessario assicurarsi che i tipi su cui si sta operando siano vicini e per determinati tipi, gli intervalli di tipi, la precisione e/o la scala potrebbero essere leggermente diversi. Inoltre, U-SQL e Spark considerano null i valori in modo diverso.

Tipi di dati

La tabella seguente fornisce i tipi equivalenti in Spark, Scala e PySpark per i tipi U-SQL specificati.

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)

Per altre informazioni, vedere:

Trattamento di NULL

In Spark i tipi per impostazione predefinita consentono valori NULL mentre in U-SQL si contrassegna in modo esplicito scalare, non oggetto come nullable. Anche se Spark consente di definire una colonna come non nullable, non applichererà il vincolo e potrebbe causare un risultato errato.

In Spark, NULL indica che il valore è sconosciuto. Un valore SPARK NULL è diverso da qualsiasi valore, incluso se stesso. I confronti tra due valori SPARK NULL o tra un valore NULL e qualsiasi altro valore restituiscono sconosciuti perché il valore di ogni null è sconosciuto.

Questo comportamento è diverso da U-SQL, che segue la semantica C#, dove null è diverso da qualsiasi valore ma uguale a se stesso.

Di conseguenza, un'istruzione SparkSQL SELECT che usa restituisce WHERE column_name = NULL zero righe anche se sono presenti valori NULL in column_name, mentre in U-SQL restituirà le righe in cui column_name è impostato su null. Analogamente, un'istruzione Spark SELECT che usa restituisce WHERE column_name != NULL zero righe anche se sono presenti valori non Null in column_name, mentre in U-SQL restituirà le righe con valori non Null. Pertanto, se si desidera la semantica di controllo null U-SQL, è consigliabile usare rispettivamente isnotnull e isnotnull (o il relativo equivalente DSL).

Trasformare gli oggetti del catalogo U-SQL

Una differenza importante è che gli script U-SQL possono usare i relativi oggetti catalogo, molti dei quali non hanno equivalenti Spark diretti.

Spark offre il supporto per i concetti dell'archivio meta Hive, principalmente database, tabelle e viste, in modo da poter eseguire il mapping di schemi e database U-SQL a database Hive e tabelle U-SQL alle tabelle Spark (vedere Spostamento di dati archiviati nelle tabelle U-SQL), ma non supporta funzioni con valori di tabella , stored procedure, assembly U-SQL, origini dati esterne e così via.

Gli oggetti di codice U-SQL, ad esempio viste, FUNZIONI, stored procedure e assembly, possono essere modellati tramite funzioni e librerie di codice in Spark e a cui viene fatto riferimento usando i meccanismi di astrazione procedurale e di funzione del linguaggio host, ad esempio tramite l'importazione di moduli Python o il riferimento a funzioni Scala.

Se il catalogo U-SQL è stato usato per condividere dati e oggetti di codice tra progetti e team, è necessario usare meccanismi equivalenti per la condivisione (ad esempio, Maven per la condivisione di oggetti di codice).

Trasformare espressioni di set di righe U-SQL ed espressioni scalari basate su SQL

Il linguaggio principale di U-SQL sta trasformando i set di righe ed è basato su SQL. Di seguito è riportato un elenco non esauritivo delle espressioni di set di righe più comuni offerte in U-SQL:

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

  • INNER/OUTER/CROSS/SEMIJOIN Espressioni

  • CROSS/OUTERAPPLY Espressioni

  • PIVOT/UNPIVOT Espressioni

  • VALUES Costruttore del set di righe

  • Impostare espressioni UNION/OUTER UNION/INTERSECT/EXCEPT

Inoltre, U-SQL fornisce varie espressioni scalari basate su SQL, ad esempio

  • OVER espressioni di windowing
  • varie funzioni di aggregazione e classificazione predefinite (SUMe FIRST così via)
  • Alcune delle espressioni scalari SQL più note: CASE, , LIKE(NOT) IN, ANDe OR così via.

Spark offre espressioni equivalenti sia nel formato DSL che in SparkSQL per la maggior parte di queste espressioni. Alcune delle espressioni non supportate in modo nativo in Spark dovranno essere riscritte usando una combinazione di espressioni Spark native e modelli semanticamente equivalenti. Ad esempio, OUTER UNION dovrà essere convertito nella combinazione equivalente di proiezioni e unioni.

A causa della diversa gestione dei valori NULL, un join U-SQL corrisponderà sempre a una riga se entrambe le colonne confrontate contengono un valore NULL, mentre un join in Spark non corrisponderà a tali colonne a meno che non vengano aggiunti controlli Null espliciti.

Trasformare altri concetti di U-SQL

U-SQL offre anche varie altre funzionalità e concetti, ad esempio query federate su database SQL Server, parametri, variabili scalari ed espressioni lambda, variabili di sistema, OPTION hint.

Query federate su database SQL Server/tabelle esterne

U-SQL fornisce origini dati e tabelle esterne, nonché query dirette su Azure SQL Database. Anche se Spark non offre le stesse astrazioni di oggetti, fornisce il connettore Spark per Azure SQL Database che può essere usato per eseguire query sui database SQL.

Parametri e variabili U-SQL

I parametri e le variabili utente hanno concetti equivalenti in Spark e nei linguaggi di hosting.

Ad esempio, in Scala è possibile definire una variabile con la var parola chiave :

var x = 2 * 3;
println(x)

Le variabili di sistema di U-SQL (variabili che iniziano con @@) possono essere suddivise in due categorie:

  • Variabili di sistema impostabili che possono essere impostate su valori specifici per influire sul comportamento degli script
  • Variabili di sistema informativo che informano le informazioni a livello di sistema e di processo

La maggior parte delle variabili di sistema impostabili non ha equivalenti diretti in Spark. Alcune delle variabili di sistema informativi possono essere modellate passando le informazioni come argomenti durante l'esecuzione del processo, altre possono avere una funzione equivalente nel linguaggio di hosting di Spark.

Hint U-SQL

U-SQL offre diversi modi sintattici per fornire suggerimenti per Query Optimizer e il motore di esecuzione:

  • Impostazione di una variabile di sistema U-SQL
  • una OPTION clausola associata all'espressione del set di righe per fornire un hint di dati o piano
  • hint di join nella sintassi dell'espressione join (ad esempio, BROADCASTLEFT)

Query Optimizer basato sui costi di Spark ha le proprie funzionalità per fornire suggerimenti e ottimizzare le prestazioni delle query. Fare riferimento alla documentazione corrispondente.

Passaggi successivi