HBase
 sql >> Base de données >  >> NoSQL >> HBase

Comment :inclure des bibliothèques tierces dans votre tâche MapReduce

"Ma bibliothèque est dans le chemin de classe mais je reçois toujours une exception Class Not Found dans un travail MapReduce" - Si vous rencontrez ce problème, ce blog est pour vous.

Java nécessite que les classes tierces et définies par l'utilisateur soient sur le "-classpath de la ligne de commande ” lorsque la JVM est lancée. Le script shell wrapper `hadoop` fait exactement cela pour vous en créant le chemin de classe à partir des bibliothèques principales situées dans /usr/lib/hadoop-0.20/ et /usr/lib/hadoop-0.20/lib/ répertoires. Cependant, avec MapReduce, les tentatives de tâche de votre travail sont exécutées sur des nœuds distants. Comment dire à une machine distante d'inclure des classes tierces et définies par l'utilisateur ?

Les tâches MapReduce sont exécutées dans des JVM distinctes sur TaskTrackers et vous devez parfois utiliser des bibliothèques tierces dans les tentatives de tâche map/reduce. Par exemple, vous souhaiterez peut-être accéder à HBase à partir de vos tâches cartographiques. Une façon de procéder consiste à empaqueter chaque classe utilisée dans le fichier JAR soumis. Vous devrez décompresser l'original hbase-.jar et reconditionnez toutes les classes dans votre fichier jar Hadoop pouvant être soumis. Pas bon. Ne faites pas ça :les problèmes de compatibilité des versions vont vous ronger tôt ou tard.

Il existe de meilleures façons de faire la même chose en plaçant votre jar dans un cache distribué ou en installant l'intégralité du JAR sur les nœuds Hadoop et en informant TaskTrackers de leur emplacement.

1. Incluez le JAR dans le "-libjars ” option de ligne de commande de la commande `hadoop jar …`. Le fichier jar sera placé dans un cache distribué et sera mis à la disposition de toutes les tentatives de tâche du travail. Plus précisément, vous trouverez le JAR dans l'un des ${mapred.local.dir}/taskTracker/archive/${user.name}/distcache/… sous-répertoires sur les nœuds locaux. L'avantage du cache distribué est que votre jar peut toujours être là lors de votre prochaine exécution de programme (du moins en théorie :les fichiers ne doivent être expulsés du cache distribué que lorsqu'ils dépassent la limite souple définie par le local.cache .taille variable de configuration, par défaut à 10 Go, mais votre kilométrage réel peut varier en particulier avec les dernières améliorations de sécurité). Hadoop garde une trace des modifications apportées aux fichiers de cache distribués en examinant leur horodatage de modification.

*Mise à jour du message :veuillez noter que les éléments 2 et 3 ci-dessous sont obsolètes à partir de CDH4 et ne seront plus pris en charge à partir de CDH5.

2. Incluez le JAR référencé dans le sous-répertoire lib du JAR soumis :une tâche MapReduce décompressera le JAR de ce sous-répertoire dans ${mapred.local.dir}/taskTracker/${user.name}/jobcache/$ jobid/pots sur les nœuds TaskTracker et faites pointer vos tâches vers ce répertoire pour rendre le JAR disponible pour votre code. Si les fichiers JAR sont petits, changent souvent et sont spécifiques à un travail, il s'agit de la méthode préférée.

3. Enfin, vous pouvez installer le JAR sur les nœuds du cluster. Le plus simple est de placer le JAR dans $HADOOP_HOME/lib car tout ce qui se trouve dans ce répertoire est inclus au démarrage d'un démon Hadoop. Cependant, puisque vous savez que seuls les TaskTrackers en auront besoin dans le nouveau JAR, une meilleure façon est de modifier l'option HADOOP_TASKTRACKER_OPTS dans le fichier de configuration hadoop-env.sh. Cette méthode est préférée si le JAR est lié au code exécuté sur les nœuds, comme HBase.

HADOOP_TASKTRACKER_OPTS="-classpath<colon-separated-paths-to-your-jars>"

Redémarrez les TastTrackers lorsque vous avez terminé. N'oubliez pas de mettre à jour le jar lorsque le logiciel sous-jacent change.

Toutes les options ci-dessus n'affectent que le code exécuté sur les nœuds distribués. Si votre code qui lance la tâche Hadoop utilise la même bibliothèque, vous devez également inclure le JAR dans la variable d'environnement HADOOP_CLASSPATH :

HADOOP_CLASSPATH="<colon-separated-paths-to-your-jars>"

Notez qu'à partir de Java 1.6, le chemin de classe peut pointer vers des répertoires tels que "/path/to/your/jars/* ” qui récupèrera tous les fichiers JAR du répertoire donné.

Les mêmes principes directeurs s'appliquent aux bibliothèques de code natif qui doivent être exécutées sur les nœuds (canaux JNI ou C++). Vous pouvez les mettre en cache distribué avec les "-fichiers ", incluez-les dans les fichiers d'archive spécifiés avec les options "-archives ” ou installez-les sur les nœuds du cluster. Si l'éditeur de liens de bibliothèque dynamique est correctement configuré, le code natif doit être mis à la disposition de vos tentatives de tâche. Vous pouvez également modifier explicitement l'environnement des tentatives de tâche en cours d'exécution du travail en spécifiant les variables JAVA_LIBRARY_PATH ou LD_LIBRARY_PATH :

hadoop jar <your jar> [main class]
      -D mapred.child.env="LD_LIBRARY_PATH=/path/to/your/libs" ...