sql >> Base de Datos >  >> NoSQL >> HBase

Cómo hacerlo:Incluir bibliotecas de terceros en su trabajo de MapReduce

“Mi biblioteca está en la ruta de clases, pero sigo recibiendo una excepción Clase no encontrada en un trabajo de MapReduce”:si tiene este problema, este blog es para usted.

Java requiere que las clases definidas por el usuario y de terceros estén en la línea de comando “–classpath ” opción cuando se inicia la JVM. El script de shell contenedor `hadoop` hace exactamente esto por usted mediante la creación de la ruta de clases a partir de las bibliotecas centrales ubicadas en /usr/lib/hadoop-0.20/ y /usr/lib/hadoop-0.20/lib/ directorios. Sin embargo, con MapReduce, los intentos de tareas de su trabajo se ejecutan en nodos remotos. ¿Cómo le dices a una máquina remota que incluya clases de terceros y definidas por el usuario?

Los trabajos de MapReduce se ejecutan en JVM separadas en TaskTrackers y, a veces, necesita usar bibliotecas de terceros en los intentos de asignación/reducción de tareas. Por ejemplo, es posible que desee acceder a HBase desde sus tareas de mapa. Una forma de hacer esto es empaquetar cada clase utilizada en el JAR que se puede enviar. Deberá descomprimir el hbase-.jar original y vuelva a empaquetar todas las clases en su jar de Hadoop que se puede enviar. No es bueno. No hagas esto:los problemas de compatibilidad de versiones te afectarán tarde o temprano.

Hay mejores formas de hacer lo mismo colocando su jar en caché distribuida o instalando el JAR completo en los nodos de Hadoop e informando a TaskTrackers sobre su ubicación.

1. Incluir el JAR en “-libjars ” opción de línea de comando del comando `hadoop jar …`. El jar se colocará en caché distribuida y estará disponible para todos los intentos de tareas del trabajo. Más específicamente, encontrará el JAR en uno de los ${mapred.local.dir}/taskTracker/archive/${user.name}/distcache/… subdirectorios en nodos locales. La ventaja de la caché distribuida es que su jar aún podría estar allí en su próxima ejecución del programa (al menos en teoría:los archivos deben eliminarse de la caché distribuida solo cuando excedan el límite flexible definido por local.cache .tamaño variable de configuración, el valor predeterminado es 10 GB, pero su kilometraje real puede variar particularmente con las mejoras de seguridad más recientes). Hadoop realiza un seguimiento de los cambios en los archivos de caché distribuidos al examinar su marca de tiempo de modificación.

*Actualizar para publicar:tenga en cuenta que los elementos 2 y 3 a continuación están obsoletos a partir de CDH4 y ya no serán compatibles a partir de CDH5.

2. Incluya el JAR al que se hace referencia en el subdirectorio lib del JAR que se puede enviar:un trabajo de MapReduce descomprimirá el JAR de este subdirectorio en ${mapred.local.dir}/taskTracker/${user.name}/jobcache/$ jobid/frascos en los nodos TaskTracker y apunte sus tareas a este directorio para que el JAR esté disponible para su código. Si los JAR son pequeños, cambian con frecuencia y son específicos del trabajo, este es el método preferido.

3. Finalmente, puede instalar el JAR en los nodos del clúster. La forma más sencilla es colocar el JAR en $HADOOP_HOME/lib directorio ya que todo lo de este directorio se incluye cuando se inicia un demonio de Hadoop. Sin embargo, dado que sabe que solo los TaskTrackers necesitarán estos nuevos JAR, una mejor manera es modificar la opción HADOOP_TASKTRACKER_OPTS en el archivo de configuración hadoop-env.sh. Se prefiere este método si el JAR está vinculado al código que se ejecuta en los nodos, como HBase.

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

Reinicie los TastTrackers cuando haya terminado. No olvide actualizar el archivo jar cuando cambie el software subyacente.

Todas las opciones anteriores afectan solo al código que se ejecuta en los nodos distribuidos. Si su código que inicia el trabajo de Hadoop usa la misma biblioteca, también debe incluir el JAR en la variable de entorno HADOOP_CLASSPATH:

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

Tenga en cuenta que a partir de Java 1.6 classpath puede apuntar a directorios como "/path/to/your/jars/* ” que recogerá todos los archivos JAR del directorio dado.

Los mismos principios rectores se aplican a las bibliotecas de código nativo que deben ejecutarse en los nodos (tuberías JNI o ​​C++). Puede colocarlos en la memoria caché distribuida con los "-archivos ”, inclúyalos en los archivos de almacenamiento especificados con “-archives ”, o instálelos en los nodos del clúster. Si el enlazador de bibliotecas dinámicas está configurado correctamente, el código nativo debería estar disponible para sus intentos de tareas. También puede modificar el entorno de los intentos de tareas en ejecución del trabajo explícitamente especificando las variables JAVA_LIBRARY_PATH o LD_LIBRARY_PATH:

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