Informazioni sul codice Apache Spark per sviluppatori U-SQL

Importante

Azure Data Lake Analytics è stato 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 di script U-SQL in Apache Spark.

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

Prima di iniziare a eseguire 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 fornire 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 diverse associazioni di linguaggio in Scala, Java, Python, .NET e così via, in cui si scrive principalmente il codice in uno di questi linguaggi, creare astrazioni di dati denominate set di dati distribuiti resilienti (RDD), dataframe e set di dati e quindi usare un linguaggio specifico del dominio (DSL) linQ per trasformarli. Fornisce anche SparkSQL come sottolanguage dichiarativa nel dataframe e nelle astrazioni dei set di dati. Il linguaggio DSL fornisce due categorie di operazioni, trasformazioni e azioni. L'applicazione delle 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 converte 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 inoltre 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 prendere in considerazione le 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 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 (flusso di dati).

I programmi Spark sono simili in quanto si usano connettori Spark per leggere i dati e creare i dataframe, quindi applicare le trasformazioni nei dataframe usando IL LINGUAGGIO LINQ o SparkSQL e quindi scrivere il risultato in file, tabelle Spark temporanee, alcuni tipi di linguaggio 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 l'esecuzione di codice .NET in modo nativo con .NET per Apache Spark. Ciò significa che è possibile riutilizzare alcune o tutte le funzioni definite dall'utente .NET con Spark. Si noti che U-SQL usa .NET Framework mentre .NET per Apache Spark è basato su .NET Core 3.1 o versione successiva.

Gli operatori definiti dall'utente (UDO) U-SQL usano il modello UDO U-SQL 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. Pertanto, 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, sarà necessario riscrivere le espressioni in un'espressione Spark, Scala, Java o Python equivalente, funzione, aggregatore o connettore Python.

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 riguardano i 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 U-SQL scalari inline 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 sparkSQL) e consente di chiamare nelle 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 in modo nativo per ottenere il massimo 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 semantica dei tipi diversi 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 le funzioni scalari definite dall'utente e gli 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 aggregatori definiti dall'utente. Pertanto, per le funzioni definite dall'utente, è 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, applicatori 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 offre funzionalità equivalenti per alcuni operatori.

L'equivalente di Spark agli estrattori e agli outputter è i connettori Spark. Per molti estrattori U-SQL, è possibile trovare un connettore equivalente nella community di Spark. Per altri, è 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 tal caso, sarà necessario distribuire il runtime .NET Core nel cluster Spark e assicurarsi che le librerie .NET di 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 dataframe.

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 python e R, pySpark e SparkR e fornisce 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 trattano null i valori in modo diverso.

Tipo 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, vedi:

Trattamento di NULL

In Spark i tipi per impostazione predefinita consentono valori NULL mentre in U-SQL si contrassegnano in modo esplicito scalare, non oggetto come nullable. Anche se Spark consente di definire una colonna come non nullable, il vincolo non verrà applicato 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 valore NULL è sconosciuto.

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

Pertanto, 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 isull e isnotnull (o il relativo equivalente DSL).

Trasformare gli oggetti del catalogo U-SQL

Una delle principali differenze è che gli script U-SQL possono usare i relativi oggetti catalogo, molti dei quali non hanno un equivalente Spark diretto.

Spark offre il supporto per i concetti relativi all'archivio meta Hive, principalmente database, tabelle e viste, in modo da poter eseguire il mapping di database e schemi U-SQL ai database Hive e alle tabelle U-SQL (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 procedurali e della funzione del linguaggio host, ad esempio tramite l'importazione di moduli Python o il riferimento alle 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 set di righe U-SQL ed espressioni scalari basate su SQL

Il linguaggio principale di U-SQL sta trasformando set di righe ed è basato su SQL. Di seguito è riportato un elenco non completo 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

  • Espressioni PIVOT/UNPIVOT

  • 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 (SUMFIRSTe così via)
  • Alcune delle espressioni scalari SQL più note: CASE, , LIKE(NOT) IN, ANDe OR così via.

Spark offre espressioni equivalenti nel formato DSL e SparkSQL per la maggior parte di queste espressioni. Alcune 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 di SQL Server, parametri, variabili di espressione scalari e lambda, variabili di sistema, OPTION hint.

Query federate su database SQL Server/tabelle esterne

U-SQL fornisce l'origine dati e le tabelle esterne, nonché le query dirette su database SQL di Azure. Anche se Spark non offre le stesse astrazioni di oggetti, fornisce il connettore Spark per database SQL di Azure 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 relativi 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 processo

La maggior parte delle variabili di sistema impostabili non ha equivalenti diretti in Spark. Alcune delle variabili di sistema informative 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 al motore di esecuzione e a Query Optimizer:

  • 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 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