Connecter Dataïku DSS et Azure Blob Storage

Suite à l’article initial sur l’installation de la sandbox Dataïku DSS, nous allons maintenant voir comment faire interagir le studio avec un compte de stockage Azure Blob Storage. Nous souhaiterons bien sûr lire des fichiers de données mais aussi écrire des données dite “raffinées” suite aux opérations de nettoyage et de transformation pouvant être réalisées par la plateforme de Dataïku.

Les tests relatés ci-dessous ont été réalisés avec ma collègue Sulan LIU.

Création d’un compte de stockage blob

Nous disposons d’un compte de stockage créé sur le portail Azure, dans lequel nous pourrons définir plusieurs conteneurs (containers). Nous verrons ci-dessous l’intérêt de disposer de plusieurs de ces répertoires physiques.

A partir du menu DSS settings puis Connections, nous pouvons cliquer sur le bouton “+NEW CONNECTION” et choisir le cloud storage Azure Blob Storage.

Nous allons maintenant détailler les principales options disponibles pour définir cette connexion.

Connection

La première information attendue est le nom que portera cette connexion du sein du Data Science Studio.

Nous pouvons ensuite choisir entre deux modes d’authentification vis à vis de la ressource Azure.

Le premier mode donne un accès total au compte de stockage au moyen du nom du compte de stockage et de la clé d’accès du compte de stockage. Selon les données contenues sur ce stockage, ce mode de connexion ne sera sans doute pas recommandé.

Nous pourrons préférer le mode de connexion “OAuth from App” correspondant à un principal de service déclaré dans l’annuaire Azure Active Directory.

Après la création du principal de service (menu “app registration”), il faut créer un secret associé.

Il sera bien sûr nécessaire de donner à cette identité des droits “Storage Blob Data Contributor” sur la ressource de stockage Azure.

Path restriction and default container

Une connexion peut être définie vers la totalité des containers ou avec une restriction sur l’un d’eux. Une bonne pratique me semble être de définir une connexion par conteneur, afin de bien isoler les rôles (données brutes en entrée, données préparées intermédiaires, prévisions en batch…).

Si l’on ne définit pas de conteneur dans la connexion, il est impératif qu’un conteneur par défaut existe. Sans modification de la valeur par défaut, celui-ci doit être nommé dataiku (sans tréma sur le i).

Security settings

Les paramètres de sécurité vont enfin permettre de donner des droits d’utilisation à tous les utilisateurs “analysts” ou bien seulement à des groupes.

Une bonne pratique consistera à ne donner l’autorisation “Details readable” qu’à un groupe administrateur de la plateforme. En effet, ce droit donne accès à la configuration de la connexion et donc par exemple à l’App ID (client ID) du principal de service.

Lecture et écriture de jeux de données

Nous pouvons maintenant démarrer un nouveau projet au sein du Data Science Studio et nous commençons logiquement par la définition d’un premier dataset.

Nous vérifions que la connexion précédemment définie apparaît bien dans la première liste déroulante.

Il sera ensuite nécessaire de cliquer sur le bouton FETCH LIST pour voir apparaître les containers autorisés.

Le bouton BROWSE permet alors de choisir le fichier voulu.

Un message nous informe du bon parsing (séparation des colonnes) du fichier.

Un aperçu du jeu de données (PREVIEW) est alors disponible et nous pouvons voir que les colonnes ont été automatiquement typées. Un rapide contrôle visuel sera toutefois souhaitable. Nous pouvons par exemple rencontrer une colonne dont les premières valeurs (celles de l’aperçu) seraient vides.

Nous pouvons maintenant construire un premier flow basé sur ce jeu de données.

Nous ajoutons quelques opérations de transformation au sein d’une “recipe“.

A la fin de la préparation des données, nous définissions l’output dataset. Dans la liste déroulante “Store into”, nous retrouvons naturellement la connexion définie au compte de stockage.

Vous pourriez, à cette étape, rencontrer le message d’erreur ci-dessous.

Dataset error – Failed to check if the new dataset name is safe, there could be a problem with the database: Failed to get information for location '', caused by: NoSuchElementException: An error occurred while enumerating the result, check the original exception for details., caused by: StorageException: The specified container does not exist.

Ce message nous alerte sur le fait que le container nommé “dataiku” n’a pas été créé. Veuillez vérifier ce point, présenté en tout début d’article.

Nous vérifions que le dataset s’est bien enregistré dans le container du compte de stockage.

Nous remarquons que le dataset, enregistré au format CSV et compressé (.gz), est partitionné automatiquement. Nous disposons de trois choix de format, le format Avro étant un format dit orienté colonne et également compressé.

Dans la version sandbox de Dataïku DSS, nous ne pourrons en revanche pas utiliser une ressource de type Azure Synapse Analytics pour lire et écrire des données. En effet, un driver JDBC est nécessaire mais les répertoires de la machine virtuelle ne sont pas accessibles. Nous aborderons donc la version Enterprise de Dataïku DSS dans de prochaines articles.

Utiliser Dataïku DSS sur Azure (sandbox)

En France, le milieu de la Data Science connaît bien, de réputation au moins, la société Dataïku et son Data Science Studio qui s’est imposé comme l’une des plateformes SaaS les plus performantes du marché. Le cadran Gartner a reconnu la société qui est aujourd’hui implantée à New-York.

Si la plateforme peut être installée sur les serveurs de l’entreprise, il est également possible de l’utiliser, supportée par les ressources du Cloud, en particulier, le cloud Azure de Microsoft.

Utiliser Dataïku DSS au sein d’Azure

Nous allons commencer par créer un groupe de ressources Azure dédié à Dataïku DSS.

Dans la Market Place Azure, nous trouvons deux entrées :

  • Dataïku Enterprise Ready AI
  • Dataïku Trial (sandbox)

Nous allons commencer par la version “bac à sable” et de prochains articles traiteront de la version Enterprise.

La tarification se fait sur le temps où la machine virtuelle Linux est allumée, et en fonction du type de machine choisie.

Le choix de la configuration d’installation se fait entre deux modes :

  • Dev/Test
  • Production

La configuration de la machine virtuelle se termine en choisissant une image contenant l’installation de Dataïku DSS.

Nous disposerons ainsi de la version 9 de Dataïku DSS, dont le descriptif est disponible sur cette page.

Il sera sûrement nécessaire de se connecter directement à cette machine et nous choisissons le mode SSH, qui demandera la création d’un clé privée, à télécharger sur le poste depuis lequel nous accèderons à la machine. Pensez à utiliser WSL pour faciliter toutes les opérations en lien avec les machines virtuelles Linux ! Mais attention, en version sandbox, les répertoires d’installation de Dataïku ne seront pas accessibles. Cela nous empêchera en particulier d’installer un driver JDBC nécessaire pour communiquer avec une ressource Azure Synapse Analytics mais nous y reviendrons dans un prochain article.

Il ne sera enfin pas possible de se connecter avec une identité présente dans l’annuaire Azure AD.

Nous terminons le processus de création sur un récapitulatif tarifaire, indiquant bien que nous ne serons facturés que sur l’utilisation de la machine virtuelle.

Il suffit maintenant de saisir l’IP publique de la machine virtuelle Linux dans un navigateur (connexion http non sécurisée pouvant lever une alerte dans votre navigateur).

Sans licence, nous cliquons sur “NO” afin d’entamer la phase d’évaluation du produit ou son utilisation gratuite (Free Edition).

Le Studio est maintenant prêt et nous disposons d’un login / password (admin /admin par défaut) pour nous reconnecter ultérieurement.

Nous voici dans le Data Science Studio.

Si vous utilisez à plusieurs cette ressource, il est recommandé de créer d’autres comptes utilisateurs.

De prochains articles viendront présenter les interactions de Dataïku DSS avec différentes ressources Azure :

  • Azure Storage Account (blob ou Data Lake gen2) pour le stockage de données
  • Azure Synapse Analytics – SQL pool (anciennement DataWarehouse) comme source de données ou cible d’écriture
  • Azure Synapse Analytics – Spark pool comme ressource de calcul, en particulier pour les entrainements
  • Azure Kubernetes Services en particulier pour le serving de modèles

Orchestrer des jobs multi-tâches avec Databricks

Le cluster Spark managé que propose Azure Databricks permet l’exécution de code, présent dans des notebooks, dans des scripts Python ou bien packagés dans des artefacts JAR (Java) ou Wheel (Python). Si l’on imagine une architecture de production, il est nécessaire de disposer d’un ordonnanceur (scheduler) afin de démarrer et d’enchaîner les différentes tâches automatiquement.

Nous connaissions déjà les jobs Databricks, nous pouvons dorénavant enchaîner plusieurs tasks au sein d’un même job. Chaque task correspond à l’exécution d’un des éléments cités ci-dessus (notebook, script Python, artefact…). Comme il s’agit à ce jour (mars 2022) d’une fonctionnalité en préversion, il est nécessaire de l’activer dans les Workspace Settings de l’espace de travail.

Le principal intérêt d’enchainer des tasks à l’intérieur d’un même job est de conserver le même job cluster, qui se différencie des interactive clusters par… sa tarification ! En effet, celui-ci est environ deux fois moins cher qu’un cluster utilisé par exemple pour des explorations menés par les Data Scientists.

Le menu latéral nous permet de lancer la création d’un nouveau job (pensez à bien le nommer dans la case située en haut à gauche).

Pour réaliser nos premiers tests, nous utiliserons un job cluster de type “single node”, associée à une machine virtuelle relativement petite.

Le job se planifie à un moment donné, défini par une interface graphique ou une syntaxe classique de type CRON telle que : 31 45 20 * * ?

Syntaxe CRON : 31 45 20 * * ?

Nous pourrons retrouver tous les logs d’exécution dans l’interface “jobs” de l’espace de travail.

Passer des informations d’une tâche à une autre

L’enchainement de tâches nous pousse rapidement à imaginer des scénarios où une information pourrait être l’output d’une tâche et l’input de la suivante. Malheureusement, il n’existe pas à ce jour de fonctionnalité native pour répondre à ce besoin. Nous allons toutefois explorer ci-dessous deux possibilités. Il existe également quelques variables réservées pouvant être passées en paramètres de la tâche : job_id, run_id, start_date…

Passer un DataFrame à une autre tâche

Nous nous orienterons tout naturellement vers le stockage d’une table dans le metastore de l’espace de travail Databricks.

  • écriture d’un DataFrame en table : df = spark.read.parquet(‘dbfs:/databricks-datasets/credit-card-fraud/data/’)
  • lecture de la table : df = spark.table(“T_credit_fraud”)

Ceci ne peut être réalisé avec une vue temporaire, créée au moyen de la fonction createOrReplaceTempView(), celle-ci disparaissant en dehors de l’environnement créé pour son notebook d’origine.

Passer une valeur à une autre tâche

Nous profitons du fait que le job cluster soit commun aux différentes tâches pour utiliser le point de montage /databricks et y écrire un fichier. Nous pouvons ainsi exploiter les commandes dbutils et shell (magic command %sh) :

  • dbutils.fs.mkdirs() permet de créer un répertoire temporaire
  • dbutils.fs.put() écrit une chaîne de texte dans un fichier

Nous vérifions ici la bonne écriture de la valeur attendue mais la commande shell cat ne permet pas de stocker le résultat dans une variable. Nous utiliserons une commande Python open() en prenant soin de préfixer par /dbfs le chemin du fichier créé lorsla tâche précédente. Attention également à bien récupérer le premier élément de la liste lines avec [0] puis à convertir la valeur dans le type attendu.

Quand continuer à utiliser Azure Data Factory ?

Dans une architecture data classique sous Azure, et orientée autour des outils PaaS, c’est le service Azure Data Factory qui est généralement utilisé comme ordonnanceur.

Si l’enchainement des tâches peut se conditionner en utilisant le nom des tâches précédentes, celui-ci n’aura lieu qu’en cas de succès des autres tâches.

Il n’est donc pas possible de prévoir un scénario similaire à celui présenté ci-dessous, où l’enchainement se ferait sur échec d’une étape précédente.

Les déclenchements de jobs Databricks ne se font que sur une date / heure alors qu’il serait possible dans Azure Data Factory de détecter l’arrivée d’un fichier, par exemple dans un compte de stockage Azure, puis de déclencher un traitement par notebook Databricks.

Template “Transformation with Azure Databricks”

Côté fonctionnalité de Data Factory, nous attendons que les activités Databricks puissent exécuter également des packages Wheel, comme il est aujourd’hui possible de le faire pour les JAR. Une solution de contournement consistera à utiliser la nouvelle version de l’API job de Databricks (2.1) dans une activité de type Web.

En conclusion, il s’agit là d’une première avancée vers l’intégration dans Databricks d’un nouvel outil indispensable à une approche DataOps ou MLOps, même si celui-ci est pour l’instant incomplet. Les fonctionnalités de Delta Live Tables, encore en préversion également, viendront aussi compléter les tâches traditionnellement dévolues à un ETL.