HBase
 sql >> Base de Dados >  >> NoSQL >> HBase

Como:incluir bibliotecas de terceiros em seu trabalho MapReduce


“Minha biblioteca está no classpath, mas ainda recebo uma exceção Class Not Found em um trabalho MapReduce” – Se você tiver esse problema, este blog é para você.

Java requer que classes definidas pelo usuário e de terceiros estejam no “–caminho de classe da linha de comando ” quando a JVM é iniciada. O script shell wrapper `hadoop` faz exatamente isso para você construindo o caminho de classe das bibliotecas principais localizadas em /usr/lib/hadoop-0.20/ e /usr/lib/hadoop-0.20/lib/ diretórios. No entanto, com o MapReduce, as tentativas de tarefa do seu trabalho são executadas em nós remotos. Como você diz a uma máquina remota para incluir classes de terceiros e definidas pelo usuário?

As tarefas MapReduce são executadas em JVMs separadas em TaskTrackers e, às vezes, você precisa usar bibliotecas de terceiros nas tentativas de tarefa de mapeamento/redução. Por exemplo, você pode querer acessar o HBase de dentro de suas tarefas de mapa. Uma maneira de fazer isso é empacotar todas as classes usadas no JAR que pode ser submetido. Você terá que descompactar o hbase-.jar original e reembale todas as classes em seu jar Hadoop que pode ser submetido. Não é bom. Não faça isso:os problemas de compatibilidade de versão vão te incomodar mais cedo ou mais tarde.

Existem maneiras melhores de fazer o mesmo colocando seu jar no cache distribuído ou instalando todo o JAR nos nós do Hadoop e informando aos TaskTrackers sobre sua localização.

1. Inclua o JAR no arquivo “-libjars ” opção de linha de comando do comando `hadoop jar …`. O jar será colocado em cache distribuído e ficará disponível para todas as tentativas de tarefa do job. Mais especificamente, você encontrará o JAR em um dos ${mapred.local.dir}/taskTracker/archive/${user.name}/distcache/… subdiretórios em nós locais. A vantagem do cache distribuído é que seu jar ainda pode estar lá na próxima execução do programa (pelo menos em teoria:Os arquivos devem ser expulsos do cache distribuído somente quando excederem o limite flexível definido pelo local.cache .size variável de configuração, o padrão é 10 GB, mas sua milhagem real pode variar particularmente com os aprimoramentos de segurança mais recentes). O Hadoop acompanha as alterações nos arquivos de cache distribuídos examinando seu carimbo de data e hora de modificação.

*Atualização para postagem:observe que os itens 2 e 3 abaixo estão obsoletos a partir do CDH4 e não terão mais suporte a partir do CDH5.

2. Inclua o JAR referenciado no subdiretório lib do JAR que pode ser enviado:Uma tarefa MapReduce descompactará o JAR deste subdiretório em ${mapred.local.dir}/taskTracker/${user.name}/jobcache/$ jobid/jars nos nós do TaskTracker e aponte suas tarefas para esse diretório para disponibilizar o JAR para seu código. Se os JARs forem pequenos, mudarem com frequência e forem específicos da tarefa, esse é o método preferencial.

3. Finalmente, você pode instalar o JAR nos nós do cluster. A maneira mais fácil é colocar o JAR em $HADOOP_HOME/lib diretório, pois tudo desse diretório é incluído quando um daemon do Hadoop é iniciado. No entanto, como você sabe que apenas os TaskTrackers precisarão do novo JAR, uma maneira melhor é modificar a opção HADOOP_TASKTRACKER_OPTS no arquivo de configuração hadoop-env.sh. Esse método é preferencial se o JAR estiver vinculado ao código em execução nos nós, como o HBase.
HADOOP_TASKTRACKER_OPTS="-classpath<colon-separated-paths-to-your-jars>"

Reinicie os TastTrackers quando terminar. Não se esqueça de atualizar o jar quando o software subjacente for alterado.

Todas as opções acima afetam apenas o código em execução nos nós distribuídos. Se o seu código que inicia o trabalho do Hadoop usa a mesma biblioteca, você também precisa incluir o JAR na variável de ambiente HADOOP_CLASSPATH:
HADOOP_CLASSPATH="<colon-separated-paths-to-your-jars>"

Observe que iniciar com o classpath Java 1.6 pode apontar para diretórios como “/path/to/your/jars/* ” que coletará todos os JARs do diretório fornecido.

Os mesmos princípios orientadores se aplicam às bibliotecas de código nativas que precisam ser executadas nos nós (pipes JNI ou C++). Você pode colocá-los em cache distribuído com os “-arquivos ” opções, inclua-as em arquivos especificados com o “-archives ” ou instale-os nos nós do cluster. Se o vinculador de biblioteca dinâmica estiver configurado corretamente, o código nativo deverá ser disponibilizado para suas tentativas de tarefa. Você também pode modificar o ambiente das tentativas de tarefa em execução do job explicitamente especificando as variáveis ​​JAVA_LIBRARY_PATH ou LD_LIBRARY_PATH:
hadoop jar <your jar> [main class]
      -D mapred.child.env="LD_LIBRARY_PATH=/path/to/your/libs" ...