Hadoop – Considérations pour vos librairies Java

Créé le: 2016/04/25 ; Révisé le: 2016/07/26
Thumbnail

Intro

Pour utiliser Hadoop à partir de votre application Java, il y a plusieurs points à considérer tels l’endroit où elle est exécutée et des performances que vous désirez avoir. Selon ces paramètres, vous pourrez choisir d’inclure toutes les librairies à votre application ou plutôt utiliser les librairies disponibles sur la grappe Hadoop.

Création d’applications Java

Normalement, toutes les librairies que votre application Java a besoin pour s’exécuter doivent être fournies avec votre application. Pour se faire, il est possible de :

  1. mettre tous ces jars dans un même répertoire,
  2. mettre tous ces jars à l’intérieur d’un répertoire dans votre jar (fat jar)
  3. dézipper le contenu de tous les jars dans un même emplacement et les rezipper dans un seul jar (shading).

Pour Hadoop, la première méthode n’est pas utilisée comme telle, mais semblable puisque les librairies d’Hadoop sont dans un répertoire local et disponible dans le classpath. Vous n’avez donc pas besoin de les inclure avec votre application tant que vous pouvez accéder à ce répertoire local.

Les autres librairies utilisées par votre application peuvent être fournies dans les trois façons précédemment décrites. Le plus simple est d’utiliser les deux derniers modes puisque distribuer toutes les librairies tierces à tous les nœuds est plus laborieux que de ne distribuer qu’un seul jar (ce jar contenant votre application et les librairies tierces ; pas les librairies Hadoop).

Ce document fournit plus de détails sur quand vous devriez inclure les librairies d’Hadoop avec votre application selon l’endroit où vous allez exécuter votre application et sur l’utilisation que votre application fait d’Hadoop.

Les librairies d’Hadoop

Librairies incluses (Fat jar)

Dans ce cas-ci, toutes les librairies d’Hadoop sont incluses dans votre jar. Cela permet de pouvoir exécuter cette application de n’importe quel endroit, mais cela signifie qu’un gros fichier sera distribué et répliqué partout où il doit s’exécuter et que la version d’Hadoop choisit est fixe. Ce dernier point est important, car il peut causer plusieurs problèmes si la version d’Hadoop sur la grappe est différente de celle fournie dans votre logiciel.

Ce problème de version va survenir lors des communications binaires entre les services étant donné que le protocole utilisé est Thrift. Ce protocole permet d’échanger des messages binaires très compacts, mais dès qu’un champ est ajouté, enlevé ou modifié dans une autre version, il a tendance à se briser avec des messages d’erreurs obscures. Le service le plus utilisé avec ce protocole est HDFS qui sert à gérer et utiliser les fichiers. L’accès à des données étant une fonctionnalité centrale de tout programme, ce détail est non négligeable.

Par contre, il y a une façon de contourner ce problème pour HDFS. Au lieu d’utiliser ce service, vous pouvez utiliser WebHDFS. Ce protocole utilise HTTP et n’est donc pas binaire comme Thrift. Il est alors intéressant pour effectuer des opérations entre les versions d’Hadoop, mais à un prix de devoir échanger plus d’informations avec chaque requête puisque le protocole HTTP est très verbeux. Si votre application se doit de transférer de gros fichiers, vous verrez une baisse de performances importante.

Librairie locale (Local jars)

Utiliser les librairies installées sur les ordinateurs qui sont sur la grappe permet de contrer le problème des versions puisque la version utilisée est toujours celle de la grappe. Pour toutes les applications qui sont démarrées par Hadoop, comme une application Map/Reduce, Yarn ou Spark, les librairies locales sont automatiquement disponibles dans le classpath. Si l’application est démarrée sur la grappe, mais par un utilisateur en ligne de commande, il faudra créer son propre classpath et pour obtenir les entrées à mettre dans le classpath, la commande « hadoop classpath » est très utile.

Contrairement à ce que certains pourraient penser, utiliser les librairies locales n’est pas une idée si saugrenue étant donné que c’est exactement cela qui est fait dans les applications d’entreprises Java EE. Normalement, Tomcat, WebSphere et autres conteneurs applicatifs EE ne font pas parti de l’application que vous distribuez et c’est ce qui permet à votre application d’être utilisables dans tous ces environnements. En faisait de même avec Hadoop, vous ne vous coincerez pas dans une seule version d’Hadoop et pas dans une seule distribution. Ces distributions sont d’ailleurs nombreuses telles Cloudera, MapR, Hortonworks, …

Les parties importantes d’Hadoop

Une installation d’Hadoop se compose de plusieurs composantes : les programmes binaires pour effectuer des tâches en ligne de commandes, les librairies java à utiliser avec les applications et la configuration de la grappe. Voici plus de détails.

Binaires Hadoop et les jars

Pour lancer une application Map/Reduce, yarn ou Spark, vous pouvez créer une application cliente qui va préparer et démarrer l’application à exécuter sur la grappe ou, plus simplement, utiliser la commande « hadoop », « yarn » ou « spark-submit ». Dans ce dernier cas, l’important est que les binaires soient disponibles sur le PATH et que la configuration de la grappe soit aussi disponible pour savoir où exécuter la tâche.

Configuration de la grappe Hadoop

Toujours sur une machine qui fait partie de la grappe, la configuration sera présente et disponible dans le classpath. Que l’application s’exécute dans Hadoop directement ou en périphérie en utilisant « hadoop classpath », il sera possible d’obtenir la configuration simplement en faisant « new Configuration() ». Nul besoin de savoir où les fichiers sont sur la machine puisqu’ils sont dans le classpath.

Par contre, si vous faites un « Fat jar », vous devrez savoir l’emplacement des fichiers de configuration ou encore pire, les inclure dans votre « Fat jar ». C’est pire étant donné que si vous modifiez certains paramètres de certains services, vous devrez recompiler votre application. Cela enlève un peu du dynamisme d’Hadoop.

Les nœuds

Votre application peut être démarrée à trois emplacements différents : sur la grappe, en périphérie ou complètement à l’extérieur de la grappe. Selon votre choix, certaines limitations se présenteront et guideront votre solution finale.

Hadoop-Where_to_run

Extérieur (Outside)

Si vous désirez exécuter votre logiciel sur un ordinateur qui n’a rien à voir avec la grappe Hadoop, vos possibilités sont peu nombreuses. Étant donné que vous n’avez pas accès aux binaires, aux librairies et à la configuration, vous devrez tout inclure dans votre application.

Vous pourriez vous demander dans quel cas d’utilisation cela peut se produire puisque le but d’Hadoop est de distribuer des tâches sur la grappe et non exécuter des tâches à l’extérieur de celle-ci. Quelques exemples sont :

  • Un gestionnaire de grappes qui doit accéder à plusieurs grappes différentes pour gérer les utilisateurs et peut-être même lancer des tâches.
  • Une application quelconque qui utilise une des technologies de base de données (telles Hive, Impala ou Hbase) (malgré que cette application pourrait aussi fonctionner en périphérie)

En périphérie (Edge node)

Pour une application qui utilise Hadoop, ceci est l’endroit recommandé où exécuter l’exécuter. Une machine qui est en périphérie ne fait pas partie de la grappe puisqu’elle n’a pas de services sur elle (pas de HDFS, pas de conteneur Yarn), mais elle possède les binaires, les librairies et la configuration de la grappe avec laquelle elle est associée. Cela permet de lancer votre application en ajoutant les librairies et la configuration au classpath grâce à « hadoop classpath ».

Alors, si vous avez une application qui affiche le contenu d’une base de données Impala, vous pouvez prendre une machine en périphérie. Ainsi, votre logiciel ne sera pas ralenti par les autres programmes utilisant la même grappe, puisque votre mémoire et processeur sont dédiés à vous, et vous aurez facilement accès aux fichiers de configuration.

Sur la grappe (Cluster node)

Normalement, vous ne devriez exécuter que des applications qui roulent sur Hadoop à cet endroit, soit des tâches Map/Reduce ou des services Yarn dont les ressources sont gérées par Yarn lui-même. C’est important de le spécifier puisqu’il est techniquement possible d’exécuter une application quelconque comme en mode périphérique, mais si vous le faites, les ressources de la mémoire et du processeur que votre application utilise ne seront pas prises en compte par Yarn et ces ressources pourraient être allouées à des tâches que la grappe doit exécuter. Vous allez donc affecter la grappe et la grappe va vous affecter.

Si vous utilisez cet endroit comme il se doit, votre application ou tâche est démarrée par Hadoop et vous avez les librairies et configurations dans le classpath. Si vous créez un « Fat jar » qui possède les librairies Hadoop et qu’il roule dans ce mode, vous risquez d’avoir des collisions de classes même si elles sont de la même version. Alors oui, faites un « Fat jar » qui inclut toutes vos librairies non liées à Hadoop et non, n’incluez pas les librairies Hadoop dedans.

Sommaire des emplacements

Extérieur En périphérie Sur la grappe
Binaires et jars d’Hadoop Aucune Disponible

 

Disponible
Configuration de la grappe Aucune Disponible Disponible
Technique disponible Librairies incluses

 

Configuration incluse ou générée

Librairie locale (premier choix)

 

Librairies incluses (second choix)

 

Librairie locale (premier choix)

 

Librairies incluses (non recommandé)