Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Important
Azure Data Lake Analytics a pris sa retraite le 29 février 2024. En savoir plus avec cette annonce.
Pour l’analytique des données, votre organisation peut utiliser Azure Synapse Analytics ou Microsoft Fabric.
Qu’est-ce que l’asymétrie des données ?
Brièvement indiqué, l’asymétrie des données est une valeur surreprésentée. Imaginez que vous avez attribué 50 examinateurs fiscaux pour auditer les déclarations fiscales, un examinateur pour chaque État américain. L’examinateur du Wyoming, parce que la population y est petite, n’a pas grand-chose à faire. En Californie, cependant, l’examinateur est occupé en raison de la population importante de l’État.
Dans notre scénario, les données sont réparties de manière inégale entre tous les examinateurs fiscaux, ce qui signifie que certains examinateurs doivent travailler plus que d’autres. Dans votre propre travail, vous rencontrez fréquemment des situations comme l’exemple d’examen fiscal ici. En termes plus techniques, un sommet reçoit beaucoup plus de données que ses homologues, une situation qui le conduit à travailler plus que les autres et qui finit par ralentir l'ensemble du travail. Pire encore, le travail peut échouer, car les sommets peuvent avoir, par exemple, une limitation de runtime de 5 heures et une limitation de mémoire de 6 Go.
Résolution des problèmes d’asymétrie des données
Azure Data Lake Tools pour Visual Studio et Visual Studio Code peuvent vous aider à détecter si votre travail a un problème d’asymétrie des données.
- Installer Azure Data Lake Tools pour Visual Studio
- Installer Azure Data Lake Tools pour Visual Studio Code
Si un problème existe, vous pouvez le résoudre en essayant les solutions de cette section.
Solution 1 : Améliorer le partitionnement de tables
Option 1 : Filtrer la valeur de clé biaisée à l’avance
S’il n’affecte pas votre logique métier, vous pouvez filtrer les valeurs de fréquence supérieure à l’avance. Par exemple, s’il existe de nombreux 000-000-000 dans la colonne GUID, vous pourriez ne pas vouloir agréger cette valeur. Avant d’agréger, vous pouvez écrire « WHERE GUID != « 000-000-000 » pour filtrer la valeur à haute fréquence.
Option 2 : Choisir une autre partition ou clé de distribution
Dans l’exemple précédent, si vous souhaitez uniquement vérifier la charge de travail d’audit fiscal partout dans le pays/la région, vous pouvez améliorer la distribution des données en sélectionnant le numéro d’ID comme clé. La sélection d’une autre partition ou clé de distribution peut parfois distribuer les données plus uniformément, mais vous devez vous assurer que ce choix n’affecte pas votre logique métier. Par exemple, pour calculer la somme fiscale pour chaque état, vous pouvez désigner l’état comme clé de partition. Si vous continuez à rencontrer ce problème, essayez d’utiliser l’option 3.
Option 3 : Ajouter d’autres clés de partition ou de distribution
Au lieu d’utiliser uniquement l’état comme clé de partition, vous pouvez utiliser plusieurs clés pour le partitionnement. Par exemple, envisagez d’ajouter du code postal comme autre clé de partition pour réduire les tailles de partition de données et distribuer les données de manière plus uniforme.
Option 4 : Utiliser la répartition en alternance
Si vous ne trouvez pas de clé appropriée pour la partition et la distribution, vous pouvez essayer d’utiliser la répartition équitable. La répartition ronde traite toutes les lignes de manière égale et les place aléatoirement dans des catégories correspondantes. Les données sont distribuées uniformément, mais elles perdent des informations de localité, un inconvénient qui peut également réduire les performances des travaux pour certaines opérations. En outre, si vous effectuez une agrégation de toute façon pour la clé biaisée, le problème de biais des données persistera. Pour en savoir plus sur la distribution en ronde, consultez la section Distributions de tables U-SQL dans CREATE TABLE (U-SQL) : création d'une table avec un schéma.
Solution 2 : Améliorer le plan de requête
Option 1 : Utiliser l’instruction CREATE STATISTICS
U-SQL fournit l’instruction CREATE STATISTICS sur les tables. Cette instruction fournit plus d’informations à l’optimiseur de requête sur les caractéristiques de données (par exemple, la distribution des valeurs) stockées dans une table. Pour la plupart des requêtes, l’optimiseur de requête génère déjà les statistiques nécessaires pour un plan de requête de haute qualité. Parfois, vous devrez peut-être améliorer les performances des requêtes en créant davantage de statistiques avec CREATE STATISTICS ou en modifiant la conception de requête. Pour plus d’informations, consultez la page CREATE STATISTICS (U-SQL).
Exemple de code :
CREATE STATISTICS IF NOT EXISTS stats_SampleTable_date ON SampleDB.dbo.SampleTable(date) WITH FULLSCAN;
Remarque
Les informations sur les statistiques ne sont pas mises à jour automatiquement. Si vous mettez à jour les données d’une table sans recréer les statistiques, les performances de la requête peuvent diminuer.
Option 2 : Utiliser SKEWFACTOR
Si vous souhaitez additionner la taxe pour chaque état, vous devez utiliser l’état GROUP BY, une approche qui n’évite pas le problème d’asymétrie des données. Toutefois, vous pouvez fournir un indicateur de données dans votre requête pour identifier l’asymétrie des données dans les clés afin que l’optimiseur puisse préparer un plan d’exécution pour vous.
En règle générale, vous pouvez définir le paramètre entre 0,5 et 1, où 0,5 indique peu d'asymétrie et 1 indique une asymétrie forte. Étant donné que l’indicateur affecte l’optimisation du plan d’exécution pour l’instruction actuelle et toutes les instructions en aval, veillez à ajouter l’indicateur avant l’agrégation par clé asymétrique potentielle.
SKEWFACTOR (columns) = x
Fournit un indicateur indiquant que les colonnes données ont un facteur d’asymétrie x de 0 (pas d’asymétrie) à 1 (asymétrie lourde).
Exemple de code :
//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
;
Option 3 : Utiliser ROWCOUNT
En plus de SKEWFACTOR, pour des cas de jointure à clé asymétrique spécifique, si vous savez que l’autre ensemble de lignes jointes est petit, vous pouvez indiquer à l’optimiseur en ajoutant un indicateur ROWCOUNT dans l’instruction U-SQL avant JOIN. De cette façon, l’optimiseur peut choisir une stratégie de jointure de diffusion pour améliorer les performances. N’oubliez pas que ROWCOUNT ne résout pas le problème d’asymétrie des données, mais il peut offrir une aide supplémentaire.
OPTION(ROWCOUNT = n)
Identifiez un petit jeu de lignes avant JOIN en fournissant un nombre de lignes entier estimé.
Exemple de code :
//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
;
Solution 3 : Améliorer le réducteur et le combineur définis par l’utilisateur
Vous pouvez parfois écrire un opérateur défini par l’utilisateur pour traiter la logique de processus complexe, et un réducteur et un combineur bien écrits peuvent atténuer un problème d’asymétrie des données dans certains cas.
Option 1 : Utiliser un réducteur récursif, si possible
Par défaut, un réducteur défini par l’utilisateur s’exécute en mode nonrecursif, ce qui signifie que le travail de réduction d’une clé est distribué dans un seul vertex. Toutefois, si vos données sont biaisées, les jeux de données volumineux peuvent être traités dans un seul nœud et s'exécuter pendant longtemps.
Pour améliorer les performances, vous pouvez ajouter un attribut dans votre code pour définir le réducteur à exécuter en mode récursif. Ensuite, les jeux de données volumineux peuvent être distribués à plusieurs sommets et s’exécuter en parallèle, ce qui accélère votre travail.
Pour modifier un réducteur non récursif en récursif, vous devez vous assurer que votre algorithme est associatif. Par exemple, la somme est associative et la médiane ne l'est pas. Vous devez également vous assurer que l’entrée et la sortie du réducteur conservent le même schéma.
Attribut du réducteur récursif :
[SqlUserDefinedReducer(IsRecursive = true)]
Exemple de code :
[SqlUserDefinedReducer(IsRecursive = true)]
public class TopNReducer : IReducer
{
public override IEnumerable<IRow>
Reduce(IRowset input, IUpdatableRow output)
{
//Your reducer code goes here.
}
}
Option 2 : Utiliser le mode de combinaison au niveau des lignes, si possible
Similaire à l’indicateur ROWCOUNT pour des cas de jointure de clé asymétrique spécifiques, le mode de combinaison tente de distribuer des ensembles de valeurs de clé asymétriques énormes sur plusieurs sommets afin que le travail puisse être exécuté simultanément. Le mode combineur ne peut pas résoudre les problèmes de déséquilibre des données, mais il peut fournir une assistance supplémentaire pour les ensembles de valeurs de clés déséquilibrées considérables.
Par défaut, le mode de combinaison est Plein, ce qui signifie que l'ensemble de lignes de gauche et l'ensemble de lignes de droite ne peuvent pas être séparés. La définition du mode en tant que gauche/droite/interne active la jointure au niveau des lignes. Le système sépare les ensembles de lignes correspondants et les distribue dans plusieurs sommets qui s’exécutent en parallèle. Toutefois, avant de configurer le mode de combinaison, veillez à vous assurer que les ensembles de lignes correspondants peuvent être séparés.
L’exemple suivant montre un ensemble de rangées à gauche, séparées. Chaque ligne de sortie dépend d’une seule ligne d’entrée de gauche, et elle dépend potentiellement de toutes les lignes de droite avec la même valeur de clé. Si vous définissez le mode de combinaison sur gauche, le système sépare l'énorme ensemble de lignes de gauche en petits ensembles et les attribue à plusieurs sommets.
Remarque
Si vous définissez le mode de combinaison incorrect, la combinaison est moins efficace et les résultats peuvent être incorrects.
Attributs du mode de combinaison :
SqlUserDefinedCombiner(Mode=CombinerMode.Full) : chaque ligne de sortie dépend potentiellement de toutes les lignes d’entrée de gauche et de droite avec la même valeur de clé.
SqlUserDefinedCombiner(Mode=CombinerMode.Left) : chaque ligne de sortie dépend d’une seule ligne d’entrée de gauche (et potentiellement toutes les lignes de droite avec la même valeur de clé).
qlUserDefinedCombiner(Mode=CombinerMode.Right) : chaque ligne de sortie dépend d’une seule ligne d’entrée de droite (et potentiellement toutes les lignes de gauche avec la même valeur de clé).
SqlUserDefinedCombiner(Mode=CombinerMode.Inner) : chaque ligne de sortie dépend d’une seule ligne d’entrée de gauche et de droite avec la même valeur.
Exemple de code :
[SqlUserDefinedCombiner(Mode = CombinerMode.Right)]
public class WatsonDedupCombiner : ICombiner
{
public override IEnumerable<IRow>
Combine(IRowset left, IRowset right, IUpdatableRow output)
{
//Your combiner code goes here.
}
}