Utiliser des activités personnalisées dans un pipeline Azure Data Factory ou Azure Synapse Analytics

S’APPLIQUE À : Azure Data Factory Azure Synapse Analytics

Vous pouvez utiliser deux types d’activités dans un pipeline Azure Data Factory ou Synapse.

Pour déplacer des données vers ou depuis un magasin de données que le service ne prend pas en charge, ou pour transformer et traiter les données d’une manière qui n’est pas prise en charge par le service, créez une Activité personnalisée avec votre propre logique de déplacement ou de transformation des données, et utilisez cette activité dans un pipeline. L’activité personnalisée exécute votre logique de code personnalisé sur un pool de machines virtuelles Azure Batch.

Notes

Cet article a été mis à jour pour pouvoir utiliser le module Azure Az PowerShell. Le module Az PowerShell est le module PowerShell qui est recommandé pour interagir avec Azure. Pour démarrer avec le module Az PowerShell, consulter Installer Azure PowerShell. Pour savoir comment migrer vers le module Az PowerShell, consultez Migrer Azure PowerShell depuis AzureRM vers Az.

Consultez les articles suivants si vous ne connaissez pas le service Azure Batch :

Important

Lors de la création d’un pool Azure Batch, ‘VirtualMachineConfiguration’ doit être utilisé et NON ‘CloudServiceConfiguration’. Pour plus d’informations, consultez la section Conseils de migration du pool Azure Batch.

Service lié Azure Batch

L’extrait de code JSON suivant définit un exemple de service lié Azure Batch. Pour plus d’informations, consultez Environnements Compute pris en charge

{
    "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"
            }
        }
    }
}

Pour approfondir votre connaissance du service lié Azure Batch, consultez l’article Services liés de calcul.

Activité personnalisée

L’extrait de code JSON suivant définit un pipeline avec une activité personnalisée simple. La définition de l’activité comporte une référence au service lié Azure Batch.

{
  "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"
        }
      }
    }]
  }
}

Dans cet exemple, le fichier helloworld.exe est une application personnalisée qui est stockée dans le dossier customactv2/helloworld du compte Stockage Azure utilisé dans le resourceLinkedService. L’activité personnalisée soumet cette application personnalisée pour qu’elle soit exécutée sur Azure Batch. Vous pouvez remplacer la commande par n’importe quelle application par défaut pouvant être exécutée sur le système d’exploitation cible des nœuds du pool Azure Batch.

Le tableau suivant indique les noms et les descriptions des propriétés qui sont spécifiques à cette activité.

Propriété Description Obligatoire
name Nom de l’activité dans le pipeline Oui
description Texte décrivant l’activité. Non
type Pour une activité personnalisée, le type d’activité est Custom. Oui
linkedServiceName Service lié sur Azure Batch. Pour en savoir plus sur ce service lié, consultez l’article Services liés de calcul. Oui
command Commande de l’application personnalisée à exécuter. Si l’application est déjà disponible sur le nœud du pool Azure Batch, resourceLinkedService et folderPath peuvent être ignorés. Par exemple, vous pouvez spécifier la commande pour qu’elle soit cmd /c dir, ce qui est pris en charge en mode natif par le nœud du pool Windows Batch. Oui
resourceLinkedService Le service lié Stockage Azure sur le compte de stockage où l’application personnalisée est stockée. Non *
folderPath Chemin du dossier de l’application personnalisée et de toutes ses dépendances.

Si vous avez des dépendances stockées dans les sous-dossiers (autrement dit, dans une structure de dossiers hiérarchique sous folderPath),-la structure de dossiers est aplatie lorsque les fichiers sont copiés vers Azure Batch. Autrement dit, tous les fichiers sont copiés dans un dossier unique, sans sous-dossier. Pour contourner ce problème, envisagez de compresser les fichiers, de copier le fichier compressé, puis de le décompresser avec du code personnalisé à l’emplacement souhaité.
Non *
referenceObjects Tableau des services liés et des jeux de données existants. Les services liés et les jeux de données référencés sont passés à l’application personnalisée au format JSON, votre code personnalisé pouvant ainsi référencer des ressources du service. Non
extendedProperties Propriétés définies par l’utilisateur qui peuvent être passées à l’application personnalisée au format JSON, votre code personnalisé peut ainsi référencer des propriétés supplémentaires. Non
retentionTimeInDays Durée de rétention pour les fichiers soumis pour une activité personnalisée. La valeur par défaut est de 30 jours. Non

* Les propriétés resourceLinkedService et folderPath doivent être toutes deux spécifiées ou omises.

Notes

Si vous transmettez des services liés en tant que referenceObjects dans une activité personnalisée, il est recommandé de transmettre un service lié Azure Key Vault (dans la mesure où il ne contient pas de chaînes sécurisées), et de récupérer les informations d’identification à l’aide du nom du secret directement à partir de Key Vault issu du code. Vous trouverez un exemple ici qui fait référence au service lié AKV, qui récupère les informations d’identification de Key Vault, puis accède au stockage dans le code.

Autorisations d’activité personnalisée

L’activité personnalisée définit le compte d’utilisateur automatique Azure Batch sur Accès non-administrateur avec étendue de la tâche (spécification utilisateur automatique par défaut). Vous ne pouvez pas modifier le niveau d’autorisation du compte d’utilisateur automatique. Pour plus d’informations, voir Exécuter des tâches sous des comptes d’utilisateur dans Azure Batch | Comptes d’utilisateur automatique.

Exécution de commandes

Vous pouvez exécuter directement une commande à l’aide d’une activité personnalisée. Dans l’exemple suivant, la commande « echo hello world » est exécutée sur les nœuds de pool Azure Batch cibles, et la sortie est envoyée vers 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"
      }
    }]
  }
}

Passage des objets et des propriétés

Cet exemple montre comment vous pouvez utiliser les referenceObjects et les extendedProperties pour passer des objets et des propriétés définies par l’utilisateur du service vers votre application personnalisée.

{
  "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"
        }
      }
    }]
  }
}

Lorsque l’activité est exécutée, les éléments referenceObjects et extendedProperties sont stockés dans les fichiers suivants qui sont déployés vers le même dossier d’exécution de l’application SampleApp.exe :

  • activity.json

    Stocke extendedProperties et les propriétés de l’activité personnalisée.

  • linkedServices.json

    Stocke un tableau des services liés définis dans la propriété referenceObjects.

  • datasets.json

    Stocke un tableau de jeux de données défini dans la propriété referenceObjects.

L’exemple de code suivant montre comment SampleApp.exe peut accéder aux informations nécessaires à partir de fichiers 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);
        }
    }
}

Récupérer les sorties de l’exécution

Vous pouvez démarrer une exécution de pipeline à l’aide de la commande PowerShell suivante :

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

Quand le pipeline s’exécute, vous pouvez vérifier la sortie de l’exécution à l’aide des commandes suivantes :

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"

Les éléments stdout et stderr de votre application personnalisée sont enregistrés dans le conteneur adfjobs du service lié Stockage Azure que vous avez défini lors de la création du service lié Azure Batch à l’aide d’un GUID de la tâche. Vous pouvez obtenir le chemin détaillé à partir de la sortie de l’exécution de l’activité, comme indiqué dans l’extrait de code suivant :

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"

Si vous souhaitez consommer le contenu de stdout.txt dans des activités en aval, vous pouvez obtenir le chemin du fichier stdout.txt dans l’expression « @activity(’MyCustomActivity’).output.outputs[0] ».

Important

  • Les fichiers activity.json, linkedServices.json et datasets.json sont stockés dans le dossier d’exécution de la tâche de traitement par lots. Pour cet exemple, les fichiers activity.json, linkedServices.json et datasets.json sont stockés dans le chemin d’accès https://adfv2storage.blob.core.windows.net/adfjobs/<GUID>/runtime/. Si nécessaire, vous devez les nettoyer séparément.
  • Pour les services liés qui utilisent le runtime d’intégration auto-hébergé, les informations sensibles comme les clés ou les mots de passe sont chiffrées par le runtime d’intégration auto-hébergé pour faire en sorte que les informations d’identification restent dans l’environnement de réseau privé défini par le client. Certains champs sensibles peuvent manquer lorsqu’ils sont référencés par votre code d’application personnalisé de cette façon. Au besoin, utilisez SecureString dans extendedProperties au lieu d’utiliser une référence de service lié.

Passer les sorties à une autre activité

Vous pouvez renvoyer les valeurs personnalisées figurant dans le code d’une activité personnalisée au service. Pour cela, vous devez les écrire dans le fichier outputs.json de votre application. Le service copie le contenu de outputs.json et l’ajoute à la sortie d’activité comme valeur de la propriété customOutput. (La taille limite est de 2 Mo.) Si vous souhaitez utiliser le contenu de outputs.json dans des activités en aval, vous pouvez obtenir la valeur à l’aide de l’expression @activity('<MyCustomActivity>').output.customOutput.

Récupérer les sorties SecureString

Les valeurs de propriété sensibles désignées en tant que type SecureString, comme illustré dans certains exemples de cet article, sont masquées dans l’onglet Surveillance de l’interface utilisateur. Lors de l’exécution réelle du pipeline, cependant, une propriété SecureString est sérialisée au format JSON dans le fichier activity.json en tant que texte brut. Par exemple :

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

Cette sérialisation n’est pas véritablement sécurisée et n’est pas destinée à être sécurisée. L’objectif est d’indiquer au service de masquer la valeur dans l’onglet Analyse.

Pour accéder aux propriétés de type SecureString à partir d’une activité personnalisée, lisez le fichier activity.json, placé dans le même dossier que le fichier EXE, désérialisez le code JSON, puis accédez à la propriété JSON (extendedProperties => [propertyName] => valeur).

Comparer les activités personnalisées de la version 2 et les activités DotNet (personnalisées) de la version 1

Dans la version 1 d’Azure Data Factory, pour implémenter une activité DotNet (personnalisée), on crée un projet de bibliothèque de classes .NET avec une classe qui implémente la méthode Execute de l’interface IDotNetActivity. Les services liés, les jeux de données et les propriétés étendues de la charge utile JSON d’une activité DotNet (personnalisée) sont transmis à la méthode d’exécution sous forme d’objets fortement typés. Pour plus d’informations sur le comportement de la version 1, consultez la page DotNet (personnalisé) dans la version 1. À cause de cette implémentation, le code de votre activité DotNet de la version 1 doit cibler .NET Framework 4.5.2. L’activité DotNet de la version 1 doit également être exécutée sur des nœuds de pools Azure Batch Windows.

Dans une activité personnalisée des pipelines Azure Data Factory V2 et Synapse, il n’est pas obligatoire d’implémenter une interface .NET. Vous pouvez maintenant exécuter directement des commandes, des scripts et votre propre code compilé sous forme d’exécutable. Pour configurer cette implémentation, spécifiez la propriété Command conjointement avec la propriété folderPath. L’activité personnalisée charge l’exécutable et ses dépendances sur folderpath et exécute la commande automatiquement.

Les services liés, les jeux de données (définis dans referenceObjects) et les propriétés étendues définis dans la charge utile JSON d’une activité personnalisée de pipeline Data Factory V2 ou Synapse sont accessibles par le biais de l’exécutable sous forme de fichiers JSON. Vous pouvez accéder aux propriétés requises à l’aide du sérialiseur JSON, comme dans l’exemple de code SampleApp.exe précédent.

Grâce aux modifications introduites dans l’activité personnalisée de pipeline Azure Data Factory V2 et Synapse, vous pouvez écrire votre logique de code personnalisée dans le langage de votre choix et l’exécuter sur les systèmes d’exploitation Windows et Linux pris en charge par Azure Batch.

Le tableau suivant décrit les différences qui existent entre l’activité personnalisée de pipeline Data Factory V2 et Synapse et l’activité DotNet (personnalisée) de la version 1 de Data Factory :

Différences Activité personnalisée Activité DotNet (personnalisée) de la version 1
Mode de définition de la logique personnalisée En fournissant un exécutable En implémentant une DLL .NET
Environnement d’exécution de la logique personnalisée Windows ou Linux Windows (.NET Framework 4.5.2)
Exécution des scripts Prend en charge l’exécution directe de scripts (par exemple « cmd /c echo hello world » sur une machine virtuelle Windows) Nécessite une implémentation dans la DLL .NET
Jeu de données nécessaire Facultatif Nécessaire pour chaîner des activités et passer des informations
Passer des informations entre l’activité et la logique personnalisée Via ReferenceObjects (LinkedServices et Datasets) et ExtendedProperties (propriétés personnalisées) et via ExtendedProperties (propriétés personnalisées), Input et Output Datasets
Récupération des informations dans la logique personnalisée Analyse activity.json, linkedServices.json et datasets.json, stockés dans le même dossier que l’exécutable Via .NET SDK (.NET Frame 4.5.2)
Journalisation Écrit directement dans STDOUT Implémentation de l’enregistreur d’événements dans la DLL .NET

S’il vous reste du code .NET écrit pour une activité DotNet (personnalisée) de la version 1, vous devez le modifier de sorte qu’il fonctionne avec la version actuelle de l’activité personnalisée. Pour mettre à jour votre code, suivez ces instructions générales :

  • Changez le projet pour qu’il s’agisse non plus d’une bibliothèque de classes .Net, mais d’une application console.
  • Démarrez votre application avec la méthode Main. La méthode Execute de l’interface IDotNetActivity n’est plus nécessaire.
  • Lisez et analyser les services liés, les jeux de données et l’activité avec un sérialiseur JSON et non en tant qu’objets fortement typés. Transmettez les valeurs des propriétés requises à la logique du code personnalisé principal. Voir l’exemple de code SampleApp.exe plus haut.
  • L’objet Enregistreur d’événements n’est plus pris en charge. La sortie de l’exécutable peut être imprimée sur la console ; elle est enregistrée dans stdout.txt.
  • Le package NuGet Microsoft.Azure.Management.DataFactories n’est plus nécessaire.
  • Compilez votre code, chargez l’exécutable et ses dépendances dans le Stockage Azure et définissez le chemin d’accès dans la propriété folderPath.

Vous trouverez un exemple complet de réécriture de l’exemple de DLL et de pipeline de bout en bout décrit dans l’article sur la version 1 de Data Factory, Utiliser des activités personnalisées dans un pipeline Azure Data Factory, en tant qu’activité personnalisée pour des pipelines Data Factory v2 ou Synapse sur la page Exemple d’activité personnalisée.

Mise à l’échelle automatique d’Azure Batch

Vous pouvez aussi créer un pool Azure Batch avec la fonctionnalité autoscale . Par exemple, vous pouvez créer un pool Azure Batch avec 0 machine virtuelle dédiée et une formule de mise à l’échelle automatique en fonction du nombre de tâches en attente.

L’exemple de formule fourni ici entraîne le comportement suivant : Lors de sa création, le pool ne contient qu’une seule machine virtuelle. La métrique $PendingTasks définit le nombre de tâches dans l’état En cours d’exécution + Actif (en file d’attente). Cette formule recherche le nombre moyen de tâches en attente au cours des 180 dernières secondes et définit TargetDedicated en conséquence. Elle garantit que TargetDedicated ne va jamais au-delà de 25 machines virtuelles. Par conséquent, à mesure que de nouvelles tâches sont envoyées, le pool s’accroît automatiquement et, au fil de la réalisation des tâches, les machines virtuelles se libèrent une à une et la mise à l’échelle automatique réduit ces machines virtuelles. Vous pouvez ajuster startingNumberOfVMs et maxNumberofVMs selon vos besoins.

Formule de mise à l’échelle automatique :

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

Pour plus d’informations, consultez Mettre automatiquement à l’échelle les nœuds de calcul dans un pool Azure Batch .

Si le pool utilise la valeur par défaut du paramètre autoScaleEvaluationInterval, le service Batch peut mettre 15 à 30 minutes à préparer la machine virtuelle avant d’exécuter l’activité personnalisée. Si le pool utilise une autre valeur pour autoScaleEvaluationInterval, le service Batch peut prendre la durée d’autoScaleEvaluationInterval + 10 minutes.

Étapes suivantes

Consultez les articles suivants qui expliquent comment transformer des données par d’autres moyens :