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

Data Factory no Microsoft Fabric é a próxima geração de Azure Data Factory, com uma arquitetura mais simples, IA interna e novos recursos. Se você não estiver familiarizado com a integração de dados, comece com Fabric Data Factory. As cargas de trabalho existentes do ADF podem ser atualizadas para Fabric para acessar novos recursos em ciência de dados, análise em tempo real e relatórios.

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 sua lógica de código personalizada em um pool Lote do Azure de máquinas virtuais.

Observação

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

Consulte os seguintes artigos caso seja novo no serviço Lote do Azure:

Importante

Ao criar um novo pool de Lote do Azure, 'VirtualMachineConfiguration' deve ser usado e NÃO 'CloudServiceConfiguration'.

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 selecionar ou criar um novo serviço vinculado Lote do Azure que executará a atividade personalizada.

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

  4. Selecione a guia Settings e especifique um comando a ser executado no Lote do Azure e 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 exemplo de serviço vinculado 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 mais informações sobre o serviço vinculado do Lote do Azure, consulte o artigo Compute linked services.

Atividade personalizada

O snippet de código JSON a seguir define um pipeline com uma atividade personalizada simples. A definição de atividade tem uma referência ao serviço vinculado 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, o helloworld.exe é um aplicativo personalizado armazenado na pasta customactv2/helloworld da conta Armazenamento do Azure usada no resourceLinkedService. A atividade Personalizada envia esse aplicativo personalizado a 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 de 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
nome Nome da atividade na linha de produção Sim
descrição Texto que descreve o que a atividade faz. Não
tipo Para a atividade personalizada, o tipo de atividade é Personalizado. Sim
NomeDoServiçoVinculado 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 Comando do aplicativo personalizado a ser executado. Se o aplicativo já estiver disponível no nó do pool de Lote do Azure, o resourceLinkedService e o 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. Sim
resourceLinkedService Armazenamento do Azure Serviço Vinculado à conta de Armazenamento em que 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 *
objetos de referência 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 Não
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 Não
tempoDeRetençãoEmDias O tempo de retenção dos arquivos enviados para a atividade personalizada. O valor padrão é de 30 dias. Não

* 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. Você pode encontrar um exemplo aqui que faz referência ao serviço vinculado com suporte para AKV, recupera as credenciais do Key Vault e 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 como Acesso não-admin com escopo de tarefa (a especificação padrão do usuário automático). 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 estiver em execução, você pode verificar a saída de execução usando os comandos a seguir:

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 Microsoft 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 de execução da atividade, conforme mostrado no trecho 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.
  • Para os Serviços Vinculados que usam o Self-Hosted Integration Runtime, as informações confidenciais, como chaves ou senhas, são criptografadas pelo Self-Hosted Integration Runtime 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.

Passar saídas 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 no outputs.json a partir do 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 de 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 indicação ao serviço para mascarar o valor na aba 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 Lote do Azure com o recurso autoscale. Por exemplo, você pode criar um pool de batch do Azure com 0 VMs dedicadas e uma fórmula de autoscalação 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 A escala automática de nós de computação em um pool de Lote 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: