Risolvere i problemi di asimmetria dei dati tramite Strumenti Azure Data Lake per Visual StudioResolve data-skew problems by using Azure Data Lake Tools for Visual Studio

Informazioni sull'asimmetria dei datiWhat is data skew?

In poche parole, un'asimmetria dei dati si verifica quando un valore è rappresentato in modo eccessivo.Briefly stated, data skew is an over-represented value. Si supponga di avere incaricato 50 esaminatori di imposte per controllare le dichiarazioni dei redditi, un esaminatore per ogni stato degli Stati Uniti.Imagine that you have assigned 50 tax examiners to audit tax returns, one examiner for each US state. L'esaminatore del Wyoming, che ha una popolazione ridotta, ha poco da fare.The Wyoming examiner, because the population there is small, has little to do. In California, invece, l'esaminatore è molto indaffarato a causa della popolazione di notevole entità.In California, however, the examiner is kept very busy because of the state's large population. Esempio di un problema di asimmetria dei datiData-skew problem example

In questo scenario, i dati sono distribuiti in modo non uniforme tra tutti gli esaminatori di imposta, il che significa che alcuni esaminatori lavorano di più rispetto ad altri.In our scenario, the data is unevenly distributed across all tax examiners, which means that some examiners must work more than others. Nell'attività personale, non di rado si verificano situazioni simili allo scenario degli esaminatori di imposta qui presentato.In your own job, you frequently experience situations like the tax-examiner example here. In termini più tecnici, un vertice ottiene molti più dati rispetto agli altri elementi, una situazione che costringe il vertice a lavorare di più rispetto agli altri e che, di conseguenza, rallenta l'intero processo.In more technical terms, one vertex gets much more data than its peers, a situation that makes the vertex work more than the others and that eventually slows down an entire job. Ancor peggio, il processo potrebbe avere esito negativo in quanto i vertici potrebbero presentare, ad esempio, un limite di runtime di 5 ore e un limite della memoria pari a 6 GB.What's worse, the job might fail, because vertices might have, for example, a 5-hour runtime limitation and a 6-GB memory limitation.

Risoluzione dei problemi di asimmetria dei datiResolving data-skew problems

Gli Strumenti Azure Data Lake per Visual Studio consentono di rilevare eventuali problemi di asimmetria dei dati all'interno dei processi.Azure Data Lake Tools for Visual Studio can help detect whether your job has a data-skew problem. Se si verifica un problema, è possibile risolverlo tramite le soluzioni presentate in questa sezione.If a problem exists, you can resolve it by trying the solutions in this section.

Soluzione 1. Migliorare il partizionamento delle tabelleSolution 1: Improve table partitioning

Opzione 1. Filtrare in anticipo un valore chiave differenteOption 1: Filter the skewed key value in advance

Se ciò non influisce sulla logica di business, è possibile filtrare in anticipo i valori a frequenza più elevata.If it does not affect your business logic, you can filter the higher-frequency values in advance. Ad esempio, se sono presenti molti 000-000-000 nella colonna GUID, l'utente potrebbe scegliere di non aggregare tale valore.For example, if there are a lot of 000-000-000 in column GUID, you might not want to aggregate that value. Prima di eseguire l'aggregazione, è possibile scrivere "WHERE GUID != "000-000-000"" per filtrare il valore ad alta frequenza.Before you aggregate, you can write “WHERE GUID != “000-000-000”” to filter the high-frequency value.

Opzione 2. Selezionare una chiave di partizione o distribuzione differenteOption 2: Pick a different partition or distribution key

Nell'esempio precedente, se si desidera solo verificare il carico di lavoro della verifica fiscale in tutto il paese, è possibile migliorare la distribuzione dei dati selezionando il numero ID come chiave.In the preceding example, if you want only to check the tax-audit workload all over the country, you can improve the data distribution by selecting the ID number as your key. La scelta di una chiave di partizione o distribuzione differente consente talvolta di distribuire i dati in modo più uniforme, ma è necessario verificare che la scelta non abbia impatto sulla logica di business.Picking a different partition or distribution key can sometimes distribute the data more evenly, but you need to make sure that this choice doesn’t affect your business logic. Ad esempio, per calcolare l'importo dell'imposta per ogni stato, è consigliabile specificare Stato come chiave di partizione.For instance, to calculate the tax sum for each state, you might want to designate State as the partition key. Se il problema persiste, provare con l'opzione 3.If you continue to experience this problem, try using Option 3.

Opzione 3. Aggiungere più chiavi di partizione o distribuzioneOption 3: Add more partition or distribution keys

Invece di usare solo Stato come chiave di partizione, è possibile impiegare più di una chiave per il partizionamento.Instead of using only State as a partition key, you can use more than one key for partitioning. Ad esempio, è consigliabile aggiungere un CAP come chiave di partizione aggiuntiva per ridurre le dimensioni della partizione dei dati e distribuire i dati in modo più uniforme.For example, consider adding ZIP Code as an additional partition key to reduce data-partition sizes and distribute the data more evenly.

Opzione 4. Usare la distribuzione round robinOption 4: Use round-robin distribution

Qualora non sia possibile trovare una chiave adeguata per la partizione e la distribuzione, si può usare la distribuzione round robin.If you cannot find an appropriate key for partition and distribution, you can try to use round-robin distribution. La distribuzione round robin considera tutte le righe in modo uguale e le inserisce in modo casuale nei bucket corrispondenti.Round-robin distribution treats all rows equally and randomly puts them into corresponding buckets. I dati vengono distribuiti uniformemente ma si perdono le informazioni sulla località, uno svantaggio che riduce anche le prestazioni del processo rispetto ad alcune operazioni.The data gets evenly distributed, but it loses locality information, a drawback that can also reduce job performance for some operations. In aggiunta, se si sta eseguendo un'aggregazione per risolvere un problema di chiave differente, il problema dell'asimmetria dei dati non verrà risolto.Additionally, if you are doing aggregation for the skewed key anyway, the data-skew problem will persist. Per altre informazioni sulla distribuzione round robin, vedere la sezione U-SQL Table Distributions (Distribuzioni di tabelle U-SQL) in CREATE TABLE (U-SQL): Creating a Table with Schema (CREATE TABLE (U-SQL): creazione di una tabella con Schema).To learn more about round-robin distribution, see the U-SQL Table Distributions section in CREATE TABLE (U-SQL): Creating a Table with Schema.

Soluzione 2. Migliorare il piano di querySolution 2: Improve the query plan

Opzione 1. Usare l'istruzione CREATE STATISTICSOption 1: Use the CREATE STATISTICS statement

U-SQL fornisce l'istruzione CREATE STATISTICS nelle tabelle.U-SQL provides the CREATE STATISTICS statement on tables. Questa istruzione offre al Query Optimizer altre informazioni relative alle caratteristiche dei dati, ad esempio la distribuzione dei valori, archiviati in una tabella.This statement gives more information to the query optimizer about the data characteristics, such as value distribution, that are stored in a table. Per la maggior parte delle query, il Query Optimizer genera già le statistiche necessarie per un piano di query di elevata qualità.For most queries, the query optimizer already generates the necessary statistics for a high-quality query plan. In alcuni casi, potrebbe essere necessario migliorare le prestazioni delle query creando statistiche aggiuntive con CREATE STATISTICS o modificando la struttura delle query.Occasionally, you might need to improve query performance by creating additional statistics with CREATE STATISTICS or by modifying the query design. Per altre informazioni, vedere la pagina CREATE STATISTICS (U-SQL) (CREATE STATISTICS (U-SQL)).For more information, see the CREATE STATISTICS (U-SQL) page.

Esempio di codice:Code example:

CREATE STATISTICS IF NOT EXISTS stats_SampleTable_date ON SampleDB.dbo.SampleTable(date) WITH FULLSCAN;

Nota

Le informazioni statistiche non vengono aggiornate in automatico.Statistics information is not updated automatically. Se si aggiornano i dati in una tabella senza generare nuovamente le statistiche, le prestazioni delle query potrebbero risultare ridotte.If you update the data in a table without re-creating the statistics, the query performance might decline.

Opzione 2. Utilizzo di SKEWFACTOROption 2: Use SKEWFACTOR

Se si desidera sommare le imposte per ogni stato, è necessario usare lo stato GROUP BY, un approccio che non evita il problema dell'asimmetria dei dati.If you want to sum the tax for each state, you must use GROUP BY state, an approach that doesn't avoid the data-skew problem. Tuttavia, è possibile inserire un suggerimento dati nella query per identificare le asimmetrie dei dati nelle chiavi, in modo da preparare un piano di esecuzione personale.However, you can provide a data hint in your query to identify data skew in keys so that the optimizer can prepare an execution plan for you.

In genere, è possibile impostare il parametro su 0,5 e 1, laddove 0,5 indica un'asimmetria non netta, mentre 1 indica un'asimmetria marcata.Usually, you can set the parameter as 0.5 and 1, with 0.5 meaning not much skew and 1 meaning heavy skew. Dal momento che il suggerimento ha un impatto sull'ottimizzazione del piano di esecuzione per l'istruzione corrente e per tutte quelle successive, è quindi necessario assicurarsi di aggiungerlo prima della potenziale aggregazione a livello della chiave con asimmetria.Because the hint affects execution-plan optimization for the current statement and all downstream statements, be sure to add the hint before the potential skewed key-wise aggregation.

SKEWFACTOR (columns) = x

Provides a hint that the given columns have a skew factor x from 0 (no skew) through 1 (very heavy skew).

Esempio di codice:Code example:

//Add a SKEWFACTOR hint.
@Impressions =
    SELECT * FROM
    searchDM.SML.PageView(@start, @end) AS PageView
    OPTION(SKEWFACTOR(Query)=0.5)
    ;

//Query 1 for key: Query, ClientId
@Sessions =
    SELECT
        ClientId,
        Query,
        SUM(PageClicks) AS Clicks
    FROM
        @Impressions
    GROUP BY
        Query, ClientId
    ;

//Query 2 for Key: Query
@Display =
    SELECT * FROM @Sessions
        INNER JOIN @Campaigns
            ON @Sessions.Query == @Campaigns.Query
    ;   

Opzione 3: Usare ROWCOUNTOption 3: Use ROWCOUNT

Oltre a SKEWFACTOR, per casi specifici di unioni di chiavi asimmetriche, se si sa che gli altri set di righe unite sono ridotti, è possibile indicarlo all'Optimizer tramite l'aggiunta di un suggerimento ROWCOUNT nell'istruzione U-SQL prima di JOIN.In addition to SKEWFACTOR, for specific skewed-key join cases, if you know that the other joined row set is small, you can tell the optimizer by adding a ROWCOUNT hint in the U-SQL statement before JOIN. In questo modo, l'Optimizer può scegliere una strategia di aggregazione della trasmissione per migliorare le prestazioni.This way, optimizer can choose a broadcast join strategy to help improve performance. Tenere presente che ROWCOUNT non risolve il problema dell'asimmetria dei dati, ma può offrire aiuto aggiuntivo.Be aware that ROWCOUNT does not resolve the data-skew problem, but it can offer some additional help.

OPTION(ROWCOUNT = n)

Identify a small row set before JOIN by providing an estimated integer row count.

Esempio di codice:Code example:

//Unstructured (24-hour daily log impressions)
@Huge   = EXTRACT ClientId int, ...
            FROM @"wasb://ads@wcentralus/2015/10/30/{*}.nif"
            ;

//Small subset (that is, ForgetMe opt out)
@Small  = SELECT * FROM @Huge
            WHERE Bing.ForgetMe(x,y,z)
            OPTION(ROWCOUNT=500)
            ;

//Result (not enough information to determine simple broadcast JOIN)
@Remove = SELECT * FROM Bing.Sessions
            INNER JOIN @Small ON Sessions.Client == @Small.Client
            ;

Soluzione 3. Migliorare il riduttore e il combinatore definiti dall'utenteSolution 3: Improve the user-defined reducer and combiner

A volte per gestire una logica di processo complessa viene usato un operatore definito dall'utente; in alcuni casi, un riduttore e un combinatore ben scritti possono ridurre il problema dell'asimmetria dei dati.You can sometimes write a user-defined operator to deal with complicated process logic, and a well-written reducer and combiner might mitigate a data-skew problem in some cases.

Opzione 1. Usare un riduttore ricorsivo se possibileOption 1: Use a recursive reducer, if possible

Per impostazione predefinita, un riduttore definito dall'utente viene eseguito in modalità non ricorsiva, ovvero il lavoro di riduzione per una chiave verrà distribuito su un unico vertice.By default, a user-defined reducer runs in non-recursive mode, which means that reduce work for a key is distributed into a single vertex. In caso di asimmetria dei dati, i set di dati di grandi dimensioni potrebbero essere elaborati in un unico vertice e richiedere un tempo di esecuzione lungo.But if your data is skewed, the huge data sets might be processed in a single vertex and run for a long time.

Per migliorare le prestazioni, è possibile aggiungere un attributo nel codice per definire l'esecuzione del riduttore in modalità ricorsiva.To improve performance, you can add an attribute in your code to define reducer to run in recursive mode. A questo punto, i set di dati di grandi dimensioni possono essere distribuiti su più vertici ed eseguiti in parallelo, al fine di velocizzare il processo.Then, the huge data sets can be distributed to multiple vertices and run in parallel, which speeds up your job.

Per trasformare un riduttore non ricorsivo in ricorsivo è necessario assicurarsi che l'algoritmo sia associativo.To change a non-recursive reducer to recursive, you need to make sure that your algorithm is associative. Ad esempio, la somma è associativa mentre la media non lo è.For example, the sum is associative, and the median is not. È necessario anche verificare che l'input e output per il riduttore rispettino lo stesso schema.You also need to make sure that the input and output for reducer keep the same schema.

Attributo del riduttore ricorsivo:Attribute of recursive reducer:

[SqlUserDefinedReducer(IsRecursive = true)]

Esempio di codice:Code example:

[SqlUserDefinedReducer(IsRecursive = true)]
public class TopNReducer : IReducer
{
    public override IEnumerable<IRow>
        Reduce(IRowset input, IUpdatableRow output)
    {
        //Your reducer code goes here.
    }
}

Opzione 2. Usare la modalità di combinazione a livello di riga, se possibileOption 2: Use row-level combiner mode, if possible

Analogamente al suggerimento ROWCOUNT per specifici casi di unioni di chiavi asimmetriche, la modalità del combinatore tenta di distribuire set di valori di chiavi asimmetriche su più vertici, in modo da ottenere un'esecuzione simultanea.Similar to the ROWCOUNT hint for specific skewed-key join cases, combiner mode tries to distribute huge skewed-key value sets to multiple vertices so that the work can be executed concurrently. La modalità del combinatore non può risolvere il problema dell'asimmetria dei dati, ma può offrire un aiuto aggiuntivo per set di valori di chiavi asimmetriche di grandi dimensioni.Combiner mode can’t resolve data-skew issues, but it can offer some additional help for huge skewed-key value sets.

Per impostazione predefinita, la modalità del combinatore è Full, ovvero il set di righe a sinistra e il set di righe a destra non possono essere separati.By default, the combiner mode is Full, which means that the left row set and right row set cannot be separated. L'impostazione della modalità su Left/Right/Inner consente l'unione a livello di riga.Setting the mode as Left/Right/Inner enables row-level join. Il sistema separa il set di righe corrispondente e le distribuisce in più vertici che vengono eseguiti in parallelo.The system separates the corresponding row sets and distributes them into multiple vertices that run in parallel. Prima di configurare la modalità del combinatore, tuttavia, assicurarsi che sia possibile separare i set di righe corrispondente.However, before you configure the combiner mode, be careful to ensure that the corresponding row sets can be separated.

L'esempio seguente illustra un set di righe sinistro separato.The example that follows shows a separated left row set. Ogni riga di output dipende da una singola riga di input a sinistra e potenzialmente da tutte le righe a destra con lo stesso valore chiave.Each output row depends on a single input row from the left, and it potentially depends on all rows from the right with the same key value. Se si imposta la modalità del combinatore su Left, il sistema separa il grande set di righe a sinistra in set più piccoli e li assegna a più vertici.If you set the combiner mode as left, the system separates the huge left-row set into small ones and assigns them to multiple vertices.

Illustrazione della modalità del combinatore

Nota

Se si imposta la modalità del combinatore errata, la combinazione è meno efficiente e i risultati potrebbero essere errati.If you set the wrong combiner mode, the combination is less efficient, and the results might be wrong.

Attributi della modalità del combinatore:Attributes of combiner mode:

  • [SqlUserDefinedCombiner(Mode=CombinerMode.Full)]: Every output row potentially depends on all the input rows from left and right with the same key value.

  • SqlUserDefinedCombiner(Mode=CombinerMode.Left): ogni riga di output dipende da una singola riga di input a sinistra e potenzialmente da tutte le righe a destra con lo stesso valore chiave.SqlUserDefinedCombiner(Mode=CombinerMode.Left): Every output row depends on a single input row from the left (and potentially all rows from the right with the same key value).

  • SqlUserDefinedCombiner(Mode=CombinerMode.Right): ogni riga di output dipende da una singola riga di input a destra e potenzialmente da tutte le righe a sinistra con lo stesso valore chiave.qlUserDefinedCombiner(Mode=CombinerMode.Right): Every output row depends on a single input row from the right (and potentially all rows from the left with the same key value).

  • SqlUserDefinedCombiner(Mode=CombinerMode.Inner): ogni riga di output dipende da una sola riga di input a sinistra e a destra con lo stesso valore.SqlUserDefinedCombiner(Mode=CombinerMode.Inner): Every output row depends on a single input row from the left and the right with the same value.

Esempio di codice:Code example:

[SqlUserDefinedCombiner(Mode = CombinerMode.Right)]
public class WatsonDedupCombiner : ICombiner
{
    public override IEnumerable<IRow>
        Combine(IRowset left, IRowset right, IUpdatableRow output)
    {
    //Your combiner code goes here.
    }
}