Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Importante
O Azure Data Lake Analytics foi desativado em 29 de fevereiro de 2024. Saiba mais com este anúncio.
Para análise de dados, sua organização pode usar o Azure Synapse Analytics ou Microsoft Fabric.
O que é a distorção de dados?
Resumidamente, a distorção de dados é um valor sobre-representado. Imagine que você designou 50 examinadores fiscais para auditar declarações fiscais, um examinador para cada estado dos EUA. O examinador de Wyoming, porque a população lá é pequena, tem pouco a fazer. Na Califórnia, no entanto, o examinador é mantido ocupado por causa da grande população do estado.
Em nosso cenário, os dados são distribuídos de forma desigual entre todos os examinadores fiscais, o que significa que alguns examinadores devem trabalhar mais do que outros. No seu próprio trabalho, você frequentemente experimenta situações como o exemplo do examinador fiscal aqui. Em termos mais técnicos, um vértice obtém muito mais dados do que seus pares, uma situação que faz com que o vértice funcione mais do que os outros e que eventualmente retarda um trabalho inteiro. O que é pior, o trabalho pode falhar, porque vértices podem ter, por exemplo, uma limitação de tempo de execução de 5 horas e uma limitação de memória de 6 GB.
Resolvendo problemas de distorção de dados
As Ferramentas do Azure Data Lake para Visual Studio e o Visual Studio Code podem ajudar a detetar se o seu trabalho tem um problema de distorção de dados.
- Instalar o Azure Data Lake Tools para Visual Studio
- pt-PT: Instalar as Ferramentas do Azure Data Lake para o Visual Studio Code
Se existir um problema, pode resolvê-lo tentando as soluções nesta secção.
Solução 1: Melhorar o particionamento de tabelas
Opção 1: Filtrar o valor da chave distorcida com antecedência
Se isso não afetar sua lógica de negócios, você poderá filtrar os valores de frequência mais alta com antecedência. Por exemplo, se houver muitos 000-000-000 na coluna GUID, talvez não queiras agregar esse valor. Antes de agregar, você pode escrever "WHERE GUID != "000-000-000"" para filtrar o valor de alta frequência.
Opção 2: Escolha uma partição ou chave de distribuição diferente
No exemplo anterior, se você quiser apenas verificar a carga de trabalho de auditoria fiscal em todo o país/região, poderá melhorar a distribuição de dados selecionando o número de ID como sua chave. Escolher uma partição ou chave de distribuição diferente às vezes pode distribuir os dados de forma mais uniforme, mas você precisa ter certeza de que essa escolha não afeta sua lógica de negócios. Por exemplo, para calcular a soma de impostos para cada estado, convém designar Estado como a chave de partição. Se continuar a ter este problema, tente utilizar a opção 3.
Opção 3: Adicionar mais chaves de partição ou distribuição
Em vez de usar apenas Estado como chave de partição, pode-se usar mais de uma chave para particionamento. Por exemplo, considere adicionar de CEP como outra chave de partição para reduzir os tamanhos de partição de dados e distribuir os dados de forma mais uniforme.
Opção 4: Usar distribuição circular
Se não conseguir encontrar uma chave apropriada para partição e distribuição, tente usar a distribuição round-robin. A distribuição round-robin trata todas as linhas de forma igual e distribui-as aleatoriamente em compartimentos correspondentes. Os dados são distribuídos uniformemente, mas perdem informações de localidade, uma desvantagem que também pode reduzir o desempenho do trabalho para algumas operações. Além disso, se você estiver fazendo agregação para a chave distorcida de qualquer maneira, o problema de distorção de dados persistirá. Para obter mais informações sobre a distribuição round-robin, consulte a seção Distribuições de Tabela U-SQL em CREATE TABLE (U-SQL): Criar uma Tabela com Esquema.
Solução 2: Melhorar o plano de consulta
Opção 1: Use a instrução CREATE STATISTICS
O U-SQL fornece a instrução CREATE STATISTICS em tabelas. Esta instrução fornece mais informações ao otimizador de consulta sobre as características de dados (por exemplo, distribuição de valor) armazenadas em uma tabela. Para a maioria das consultas, o otimizador de consulta já gera as estatísticas necessárias para um plano de consulta de alta qualidade. Ocasionalmente, talvez seja necessário melhorar o desempenho da consulta criando mais estatísticas com CREATE STATISTICS ou modificando o design da consulta. Para obter mais informações, consulte a página CREATE STATISTICS (U-SQL).
Exemplo de código:
CREATE STATISTICS IF NOT EXISTS stats_SampleTable_date ON SampleDB.dbo.SampleTable(date) WITH FULLSCAN;
Observação
As informações estatísticas não são atualizadas automaticamente. Se você atualizar os dados em uma tabela sem recriar as estatísticas, o desempenho da consulta poderá diminuir.
Opção 2: Usar SKEWFACTOR
Se você quiser somar o imposto para cada estado, você deve usar o estado GROUP BY, uma abordagem que não evita o problema de distorção de dados. No entanto, você pode fornecer uma dica de dados em sua consulta para identificar distorção de dados em chaves para que o otimizador possa preparar um plano de execução para você.
Normalmente, você pode definir o parâmetro como 0,5 e 1, com 0,5 significando pouca inclinação e um significando inclinação pesada. Como a dica afeta a otimização do plano de execução para a instrução atual e todas as instruções subsequentes, certifique-se de adicioná-la antes da possível agregação distorcida por chave.
SKEWFACTOR (columns) = x
Fornece uma dica de que as colunas dadas têm um fator de inclinação x de 0 (sem inclinação) a 1 (inclinação pesada).
Exemplo de código:
//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
;
Opção 3: Usar ROWCOUNT
Além de SKEWFACTOR, para casos específicos de junção de chave enviesada, se souber que o outro conjunto de linhas unidas é pequeno, pode informar o otimizador adicionando uma dica ROWCOUNT na instrução U-SQL antes do JOIN. Dessa forma, o otimizador pode escolher uma estratégia de junção de emissão para ajudar a melhorar o desempenho. Esteja ciente de que ROWCOUNT não resolve o problema de distorção de dados, mas pode oferecer alguma ajuda extra.
OPTION(ROWCOUNT = n)
Identifique um pequeno conjunto de linhas antes de JOIN fornecendo uma contagem de linhas inteiras estimada.
Exemplo de código:
//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
;
Solução 3: Melhorar o redutor e o combinador definidos pelo utilizador
Às vezes, você pode escrever um operador definido pelo usuário para lidar com uma lógica de processo complicada, e um redutor e combinador bem escritos podem atenuar um problema de distorção de dados em alguns casos.
Opção 1: Use um redutor recursivo, se possível
Por padrão, um redutor definido pelo usuário é executado no modo não recursivo, o que significa que o trabalho de redução para uma chave é distribuído em um único vértice. Mas se seus dados estiverem distorcidos, os enormes conjuntos de dados podem ser processados em um único vértice e executados por um longo tempo.
Para melhorar o desempenho, você pode adicionar um atributo em seu código para definir redutor para execução no modo recursivo. Em seguida, os enormes conjuntos de dados podem ser distribuídos para vários vértices e executados em paralelo, o que acelera o seu trabalho.
Para alterar um redutor não recursivo para recursivo, você precisa ter certeza de que seu algoritmo é associativo. Por exemplo, a soma é associativa e a mediana não. Você também precisa se certificar de que a entrada e a saída para o redutor mantenham o mesmo esquema.
Atributo do redutor recursivo:
[SqlUserDefinedReducer(IsRecursive = true)]
Exemplo de código:
[SqlUserDefinedReducer(IsRecursive = true)]
public class TopNReducer : IReducer
{
public override IEnumerable<IRow>
Reduce(IRowset input, IUpdatableRow output)
{
//Your reducer code goes here.
}
}
Opção 2: Use o modo combinador ao nível da linha, se possível
Semelhante à dica ROWCOUNT para casos específicos de junção de chave enviesada, o modo combinador tenta distribuir enormes conjuntos de valores de chave enviesada por vários vértices, permitindo que o trabalho seja executado em simultâneo. O modo combinador não pode resolver problemas de distorção de dados, mas pode oferecer alguma ajuda extra para grandes conjuntos de valores de chave distorcida.
Por padrão, o modo combinador é Completo, o que significa que o conjunto de linhas esquerdo e o conjunto de linhas direito não podem ser separados. Definir o modo como Esquerda/Direita/Interior permite a junção a nível de linha. O sistema separa os conjuntos de linhas correspondentes e distribui-os em vários vértices que correm em paralelo. No entanto, antes de configurar o modo combinador, tenha cuidado para garantir que os conjuntos de linhas correspondentes possam ser separados.
O exemplo a seguir mostra um conjunto de linhas à esquerda separado. Cada linha de saída depende de uma única linha de entrada da esquerda e, potencialmente, depende de todas as linhas da direita com o mesmo valor de chave. Se definir o modo de combinação como 'esquerda', o sistema separa o enorme conjunto de linhas à esquerda em conjuntos menores e os atribui a vários vértices.
Observação
Se você definir o modo combinador errado, a combinação é menos eficiente e os resultados podem estar errados.
Atributos do modo combinador:
SqlUserDefinedCombiner(Mode=CombinerMode.Full): Cada linha de saída depende potencialmente de todas as linhas de entrada, tanto da esquerda quanto da direita, com o mesmo valor de chave.
SqlUserDefinedCombiner(Mode=CombinerMode.Left): Cada linha de saída depende de uma única linha de entrada da esquerda (e potencialmente todas as linhas da direita com o mesmo valor de chave).
qlUserDefinedCombiner(Mode=CombinerMode.Right): Cada linha de saída depende de uma única linha de entrada da direita (e potencialmente todas as linhas da esquerda com o mesmo valor de chave).
SqlUserDefinedCombiner(Mode=CombinerMode.Inner): Cada linha de saída depende de uma única linha de entrada da esquerda e da direita com o mesmo valor.
Exemplo de código:
[SqlUserDefinedCombiner(Mode = CombinerMode.Right)]
public class WatsonDedupCombiner : ICombiner
{
public override IEnumerable<IRow>
Combine(IRowset left, IRowset right, IUpdatableRow output)
{
//Your combiner code goes here.
}
}