Les workflows Oozie permettent d’utiliser plusieurs actions pour exécuter du code, cependant il peut être délicat d’exécuter du Python, nous allons voir comment faire.

J’ai récemment implémenté un workflow qui interagit avec ElasticSearch. Celui-ci contient les actions suivantes:

  • Création d’un index.
  • Ingestion d’un data set.
  • Création d’un alias si tout s’est bien passé.
  • Suppression de l’index en cas d’échec.

Il y a plusieurs manières d’interagir avec ElasticSearch: en transport binaire Java ou avec l’API REST. La plupart des langages disposent de librairies. Pour que le workflow Oozie fonctionne comme attendu, nous avons défini plusieurs conditions nécessaires:

  • Le code doit être portable, c’est à dire embarquer toutes les dépendances nécéssaires, car le cluster n’est pas connecté à internet.
  • Le code doit être facilement compréhensible et écrit dans un langage populaire pour éviter une dette technique.
  • Donner priorité à un langage dans lequel REST et JSON sont facilement manipulables.
  • L’application doit pouvoir offrir plusieurs options CLI, au moins une pour chaque action Oozie.

L’idée d’utiliser Bash s’est présentée mais le parsing des JSON renvoyés par ElasticSearch aurait été trop complexe. Nous avons donc choisi le Python.

ElasticSearch & Python

Bon à savoir: le Python est un langage très adapté pour l’interaction avec ElasticSearch.

La librairie supporte les versions 2.x à 6.x d’ElasticSearch  (cela nous arrange étant en 2.x) et est très simple d’utilisation.

Voici un exemple de code permettant d’ouvrir une connexion sécurisée et de créer un index :

Packager le code Python

Maintenant que le code est prêt, il faut le packager avec toutes ses dépendances. Le workflow doit pouvoir fonctionner sans accès internet. Seul le binaire Python est un prérequis et il est présent par défaut sur l’OS que nous utilisons, CentOS 7.

Le Python offre plusieurs possibilités pour packager des applications (Wheel, Egg (déprécié pour Wheel), Zip…) avec leurs ressources et HOWTOs. Cependant lorsqu’il s’agit de packager, faire le bon choix peut s’avérer compliqué pour un débutant. Heureusement Python supporte de manière native la possibilité de packager le répertoire de code dans un fichier zip pour pourvoir l’exécuter sous cette forme. L’archive obtenue se lance comme un fichier .py classique.

Ensuite, il nous faut télécharger toutes les dépendances en local et les inclure dans le package.

Par exemple, avec cette architecture de projet:

Nous pouvons tout packager de la manière suivante:

Et l’exécuter comme ceci:

Workflow Oozie

Maintenant que nous avons un package Python contenant nos scripts, nous pouvons l’intégrer à notre workflow Oozie.

Il n’y a malheureusement pas d’action Python dans Oozie. Nous utiliserons donc celle qui s’en rapproche le plus: l’action Shell.

Comme pour tous les types d’action, Oozie prépare un container, y injecte les fichiers spécifiés et lance une commande.

Voici comment définir l’action:

  • La configuration  spécifie une file YARN dans laquelle sera lancée le container.
  • env-var  définit les variables d’environnement du bundle Python.
  • file injecte le bundle Python dans le container de l’action Shell d’Oozie.

Bien sûr, il faut avoir Python installé sur tous les noeuds YARN (il est très souvent présent de base dans les distributions Linux, mais il est préférable d’installer une version packagée avec Anaconda par exemple).

Une fonctionnalité utile d’Oozie dans l’action Shell est le tag <capture-output/>. Il permet de capturer les logs présentés sous la même forme  property=value  pour ensuite les réutiliser dans les actions suivantes du workflow de cette manière : ${wf:actionData('python-action')['property']} .

Sources

[/fusion_builder_column][/fusion_builder_row][/fusion_builder_container]