Compartilhar via


Usar atividades personalizadas em um pipeline do Azure Data Factory ou do Azure Synapse Analytics

APLICA-SE A: Azure Data Factory Azure Synapse Analytics

Dica

Experimente o Data Factory no Microsoft Fabric, uma solução de análise tudo-em-um para empresas. O Microsoft Fabric abrange desde movimentação de dados até ciência de dados, análise em tempo real, business intelligence e relatórios. Saiba como iniciar uma avaliação gratuita!

Há dois tipos de atividades que você pode usar em um pipeline do Azure Data Factory ou do Synapse.

Para mover dados de/para um armazenamento de dados sem suporte do serviço ou para transformar/processar dados de uma forma que não tenha suporte do serviço, você pode criar uma Atividade personalizada com a sua própria lógica de movimentação ou de transformação de dados e usar essa atividade em um pipeline. A atividade personalizada executa a sua lógica de código personalizada em um pool de máquinas virtuais do Lote do Azure.

Observação

Recomendamos que você use o módulo Az PowerShell do Azure para interagir com o Azure. Para começar, confira Instalar o Azure PowerShell. Para saber como migrar para o módulo Az PowerShell, confira Migrar o Azure PowerShell do AzureRM para o Az.

Veja os artigos a seguir se você for novo no serviço de Lote do Azure:

Importante

Ao criar um novo pool do Lote do Azure, “VirtualMachineConfiguration” deve ser usado, e NÃO “CloudServiceConfiguration”. Para obter mais detalhes, veja Diretrizes de migração do pool do Lote do Azure.

Adicionar atividades personalizadas a um pipeline usando a interface do usuário

Para usar uma atividade Personalizada em um pipeline, conclua as seguintes etapas:

  1. Procure Personalizada no painel Atividades do pipeline e arraste uma atividade Personalizada para a tela do pipeline.

  2. Selecione a nova atividade Personalizada na tela se ela ainda não estiver selecionada.

  3. Selecione a guia Lote do Azure para escolher ou criar um serviço vinculado do Lote do Azure que executará a atividade personalizada.

    Mostra a interface do usuário de uma atividade personalizada.

  4. Selecione a guia Configurações e especifique um comando a ser executado no Lote do Azure e os detalhes avançados opcionais.

    Mostra a interface do usuário da guia Configurações para uma atividade personalizada.

Serviço vinculado do Lote do Azure

O JSON a seguir define um serviço vinculado de exemplo do Lote do Azure. Para saber mais, veja Ambientes de computação com suporte

{
    "name": "AzureBatchLinkedService",
    "properties": {
        "type": "AzureBatch",
        "typeProperties": {
            "accountName": "batchaccount",
            "accessKey": {
                "type": "SecureString",
                "value": "access key"
            },
            "batchUri": "https://batchaccount.region.batch.azure.com",
            "poolName": "poolname",
            "linkedServiceName": {
                "referenceName": "StorageLinkedService",
                "type": "LinkedServiceReference"
            }
        }
    }
}

Para saber mais sobre o serviço vinculado do Lote do Azure, consulte o artigo Compute linked services (Serviços de computação vinculados).

Atividade personalizada

O snippet de código JSON a seguir define um pipeline com uma atividade personalizada simples. A definição da atividade tem uma referência ao serviço vinculado do Lote do Azure.

{
  "name": "MyCustomActivityPipeline",
  "properties": {
    "description": "Custom activity sample",
    "activities": [{
      "type": "Custom",
      "name": "MyCustomActivity",
      "linkedServiceName": {
        "referenceName": "AzureBatchLinkedService",
        "type": "LinkedServiceReference"
      },
      "typeProperties": {
        "command": "helloworld.exe",
        "folderPath": "customactv2/helloworld",
        "resourceLinkedService": {
          "referenceName": "StorageLinkedService",
          "type": "LinkedServiceReference"
        }
      }
    }]
  }
}

Neste exemplo, helloworld.exe é um aplicativo personalizado armazenado na pasta customactv2/helloworld da conta de Armazenamento do Azure usada no resourceLinkedService. A atividade personalizada envia esse aplicativo personalizado para ser executado no Lote do Azure. Você pode substituir o comando para qualquer aplicativo preferencial que possa ser executado no sistema operacional de destino dos nós do pool do Lote do Azure.

A tabela a seguir descreve os nomes e as descrições de propriedades que são específicas a esta atividade.

Propriedade Descrição Obrigatório
name Nome da atividade no pipeline Sim
descrição Texto que descreve o que a atividade faz. Não
type Para a atividade personalizada, o tipo de atividade é Personalizado. Sim
linkedServiceName Serviço vinculado ao Lote do Azure. Para saber mais sobre esse serviço vinculado, consulte o artigo Compute linked services (Serviços de computação vinculados). Sim
. Comando do aplicativo personalizado a ser executado. Se o aplicativo já estiver disponível no nó do pool do Lote do Azure, resourceLinkedService e folderPath poderão ser ignorados. Por exemplo, você pode especificar o comando como cmd /c dir, que tem suporte nativo no nó do pool do Lote do Windows. Yes
resourceLinkedService Serviço de vinculado do Armazenamento do Azure para a conta de armazenamento na qual o aplicativo personalizado é armazenado Não *
folderPath Caminho para a pasta do aplicativo personalizado e de todas as suas dependências

Se você tiver dependências armazenadas em subpastas - ou seja, em uma estrutura hierárquica de pastas em folderPath - a estrutura de pastas estará nivelada quando os arquivos forem copiados para o Lote do Azure. Ou seja, todos os arquivos são copiados em uma única pasta sem subpastas. Para contornar esse comportamento, considere compactar os arquivos, copiando o arquivo compactado e, em seguida, descompactá-lo com código personalizado no local desejado.
Não *
referenceObjects Uma matriz de serviços vinculados e conjuntos de dados existentes. Os serviços vinculados e os conjuntos de dados referenciados são passados para o aplicativo personalizado no formato JSON para que o seu código personalizado possa referenciar os recursos do serviço No
extendedProperties Propriedades definidas pelo usuário que podem ser passadas para o aplicativo personalizado no formato JSON para que o seu código personalizado possa referenciar propriedades adicionais No
retentionTimeInDays O tempo de retenção dos arquivos enviados para a atividade personalizada. O valor padrão é de 30 dias. No

* As propriedades resourceLinkedService e folderPath devem ser ambas especificadas ou ambas omitidas.

Observação

Se você estiver passando serviços vinculados como referenceObjects na Atividade Personalizada, uma boa prática de segurança é passar um serviço vinculado do Azure Key Vault habilitado (uma vez que ele não contém nenhuma cadeia de caracteres segura) e buscar as credenciais com o nome secreto diretamente no Key Vault do código. Veja um exemplo aqui que faz referência ao serviço vinculado habilitado para AKV, recupera as credenciais de Key Vault e, depois, acessa o armazenamento no código.

Observação

No momento, há suporte apenas para o Armazenamento de Blobs do Azure para resourceLinkedService na atividade personalizada, e esse é o único serviço vinculado que é criado por padrão e não tem a opção de escolher outros conectores, como o ADLS Gen2.

Permissões de atividade personalizada

A atividade personalizada define a conta de usuário automático do Lote do Azure para acesso de não administrador com escopo de tarefa (a especificação de usuário automático padrão). Você não pode alterar o nível de permissão da conta de usuário automático. Para obter mais informações, veja Executar tarefas em contas de usuário no Lote | Contas de usuário automático.

Executando comandos

É possível executar diretamente um comando usando a Atividade Personalizada. O exemplo a seguir executa o comando "eco Olá, mundo" nos nós de destino do Pool do Lote do Azure e imprime a saída para stdout.

{
  "name": "MyCustomActivity",
  "properties": {
    "description": "Custom activity sample",
    "activities": [{
      "type": "Custom",
      "name": "MyCustomActivity",
      "linkedServiceName": {
        "referenceName": "AzureBatchLinkedService",
        "type": "LinkedServiceReference"
      },
      "typeProperties": {
        "command": "cmd /c echo hello world"
      }
    }]
  }
}

Passando objetos e propriedades

Este exemplo mostra como você pode usar referenceObjects e extendedProperties para passar objetos e propriedades definidas pelo usuário do serviço para seu aplicativo personalizado.

{
  "name": "MyCustomActivityPipeline",
  "properties": {
    "description": "Custom activity sample",
    "activities": [{
      "type": "Custom",
      "name": "MyCustomActivity",
      "linkedServiceName": {
        "referenceName": "AzureBatchLinkedService",
        "type": "LinkedServiceReference"
      },
      "typeProperties": {
        "command": "SampleApp.exe",
        "folderPath": "customactv2/SampleApp",
        "resourceLinkedService": {
          "referenceName": "StorageLinkedService",
          "type": "LinkedServiceReference"
        },
        "referenceObjects": {
          "linkedServices": [{
            "referenceName": "AzureBatchLinkedService",
            "type": "LinkedServiceReference"
          }]
        },
        "extendedProperties": {          
          "connectionString": {
            "type": "SecureString",
            "value": "aSampleSecureString"
          },
          "PropertyBagPropertyName1": "PropertyBagValue1",
          "propertyBagPropertyName2": "PropertyBagValue2",
          "dateTime1": "2015-04-12T12:13:14Z"
        }
      }
    }]
  }
}

Quando a atividade é executada, referenceObjects e extendedProperties são armazenados nos seguintes arquivos que são implantados na mesma pasta de execução do SampleApp.exe:

  • activity.json

    Armazena extendedProperties e as propriedades da atividade personalizada.

  • linkedServices.json

    Armazena uma matriz de serviços vinculados definidos na propriedade referenceObjects.

  • datasets.json

    Armazena uma matriz de conjuntos de dados definidos na propriedade referenceObjects.

O exemplo de código a seguir demonstra como o SampleApp.exe pode acessar as informações necessárias dos arquivos JSON:

using Newtonsoft.Json;
using System;
using System.IO;

namespace SampleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            //From Extend Properties
            dynamic activity = JsonConvert.DeserializeObject(File.ReadAllText("activity.json"));
            Console.WriteLine(activity.typeProperties.extendedProperties.connectionString.value);

            // From LinkedServices
            dynamic linkedServices = JsonConvert.DeserializeObject(File.ReadAllText("linkedServices.json"));
            Console.WriteLine(linkedServices[0].properties.typeProperties.accountName);
        }
    }
}

Recuperar as saídas de execução

É possível iniciar uma execução de pipeline, usando este comando do PowerShell:

$runId = Invoke-AzDataFactoryV2Pipeline -DataFactoryName $dataFactoryName -ResourceGroupName $resourceGroupName -PipelineName $pipelineName

Quando o pipeline é executado, verifique a saída de execução usando os seguintes comandos:

while ($True) {
    $result = Get-AzDataFactoryV2ActivityRun -DataFactoryName $dataFactoryName -ResourceGroupName $resourceGroupName -PipelineRunId $runId -RunStartedAfter (Get-Date).AddMinutes(-30) -RunStartedBefore (Get-Date).AddMinutes(30)

    if(!$result) {
        Write-Host "Waiting for pipeline to start..." -foregroundcolor "Yellow"
    }
    elseif (($result | Where-Object { $_.Status -eq "InProgress" } | Measure-Object).count -ne 0) {
        Write-Host "Pipeline run status: In Progress" -foregroundcolor "Yellow"
    }
    else {
        Write-Host "Pipeline '"$pipelineName"' run finished. Result:" -foregroundcolor "Yellow"
        $result
        break
    }
    ($result | Format-List | Out-String)
    Start-Sleep -Seconds 15
}

Write-Host "Activity `Output` section:" -foregroundcolor "Yellow"
$result.Output -join "`r`n"

Write-Host "Activity `Error` section:" -foregroundcolor "Yellow"
$result.Error -join "`r`n"

O stdout e stderr do aplicativo personalizado são salvos no contêiner adfjobs no serviço vinculado do Armazenamento do Azure que você definiu durante a criação do serviço vinculado do Lote do Azure com um GUID da tarefa. Você pode obter o caminho detalhado da saída da execução da atividade, conforme é mostrado no snippet de código a seguir:

Pipeline ' MyCustomActivity' run finished. Result:

ResourceGroupName : resourcegroupname
DataFactoryName   : datafactoryname
ActivityName      : MyCustomActivity
PipelineRunId     : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
PipelineName      : MyCustomActivity
Input             : {command}
Output            : {exitcode, outputs, effectiveIntegrationRuntime}
LinkedServiceName :
ActivityRunStart  : 10/5/2017 3:33:06 PM
ActivityRunEnd    : 10/5/2017 3:33:28 PM
DurationInMs      : 21203
Status            : Succeeded
Error             : {errorCode, message, failureType, target}

Activity Output section:
"exitcode": 0
"outputs": [
  "https://<container>.blob.core.windows.net/adfjobs/<GUID>/output/stdout.txt",
  "https://<container>.blob.core.windows.net/adfjobs/<GUID>/output/stderr.txt"
]
"effectiveIntegrationRuntime": "DefaultIntegrationRuntime (East US)"
Activity Error section:
"errorCode": ""
"message": ""
"failureType": ""
"target": "MyCustomActivity"

Se deseja consumir o conteúdo de stdout.txt nas atividades downstream, você pode obter o caminho para o arquivo stdout.txt na expressão "@activity('MyCustomActivity').output.outputs[0]".

Importante

  • O activity.json, o linkedServices.json e o datasets.json são armazenados na pasta de runtime da tarefa Batch. Para esse exemplo, o activity.json, linkedServices.json e datasets.json são armazenados no caminho https://adfv2storage.blob.core.windows.net/adfjobs/<GUID>/runtime/. Caso seja necessário, limpe-os separadamente.
  • Como os serviços vinculados que usam o Integration Runtime (auto-hospedado), as informações confidenciais, como chaves ou senhas, são criptografadas pelo Integration Runtime (auto-hospedado) para garantir que a credencial permaneça no ambiente de rede privada definido pelo cliente. Por esse motivo, alguns campos confidenciais podem ficar faltando na referência do código do aplicativo personalizado. Use SecureString em extendedProperties em vez de usar a referência do serviço vinculado, se necessário.

Saídas de passagem para outra atividade

Você pode enviar valores personalizados do seu código em uma atividade personalizada de volta para o serviço. Você pode fazer isso, escrevendo-os em outputs.json seu aplicativo. O serviço copia o conteúdo do outputs.json e acrescenta-o para a Saída da Atividade como o valor da propriedade customOutput. O limite de tamanho é 2 MB. Se você quiser consumir o conteúdo de outputs.json em atividades downstream, você poderá obter o valor usando a expressão @activity('<MyCustomActivity>').output.customOutput.

Recuperar saídas do SecureString

Os valores de propriedades confidenciais designados como tipo SecureString, conforme mostrado em alguns dos exemplos deste artigo, são mascarados na guia Monitoramento na interface do usuário. Na execução real do pipeline, no entanto, uma propriedade SecureString é serializada como JSON no arquivo activity.json como texto simples. Por exemplo:

"extendedProperties": {
  "connectionString": {
    "type": "SecureString",
    "value": "aSampleSecureString"
  }
}

Essa serialização não é verdadeiramente segura e não é destinada a ser segura. A intenção é uma dica ao serviço para mascarar o valor na guia Monitoramento.

Para acessar propriedades do tipo SecureString de uma atividade personalizada, leia o arquivo activity.json, que é colocado na mesma pasta que o .EXE, desserialize o JSON e, em seguida, acesse a propriedade JSON (extendedProperties => [propertyName] => value).

Dimensionamento automático do Lote do Azure

Você também pode criar um pool de Lotes do Azure com o recurso autoscale . Por exemplo, você poderia criar um pool do Lote do Azure sem nenhuma VM dedicada e uma fórmula de escala automática com base no número de tarefas pendentes.

A fórmula de exemplo alcança o seguinte comportamento: quando o pool é criado pela primeira vez, ele começa com uma VM. A métrica de $PendingTasks define o número de tarefas em execução + estado ativo (em fila). A fórmula localiza o número médio de tarefas pendentes nos últimos 180 segundos e define TargetDedicated adequadamente. Isso garante que TargetDedicated nunca ultrapasse 25 VMs. Assim, o pool aumenta automaticamente conforme novas tarefas são enviadas e, conforme as tarefas são concluídas, as VMs se liberam uma a uma e são reduzidas pelo dimensionamento automático. startingNumberOfVMs e maxNumberofVMs podem ser ajustados às suas necessidades.

Fórmula de dimensionamento automático:

startingNumberOfVMs = 1;
maxNumberofVMs = 25;
pendingTaskSamplePercent = $PendingTasks.GetSamplePercent(180 * TimeInterval_Second);
pendingTaskSamples = pendingTaskSamplePercent < 70 ? startingNumberOfVMs : avg($PendingTasks.GetSample(180 * TimeInterval_Second));
$TargetDedicated=min(maxNumberofVMs,pendingTaskSamples);

Consulte Dimensionar automaticamente os nós de computação em um pool de Lotes do Azure para obter detalhes.

Se o pool estiver usando o padrão autoScaleEvaluationInterval, o serviço Lote poderá demorar de 15 a 30 minutos para preparar a VM antes de executar a atividade personalizada. Se o pool estiver usando um autoScaleEvaluationInterval diferente, o serviço de lote pode levar autoScaleEvaluationInterval + 10 minutos.

Consulte os seguintes artigos que explicam como transformar dados de outras maneiras: