sql >> Databasteknik >  >> NoSQL >> HBase

Så här gör du:Inkludera tredjepartsbibliotek i ditt MapReduce-jobb

"Mitt bibliotek är i klassvägen men jag får fortfarande ett Class Not Found-undantag i ett MapReduce-jobb" – Om du har det här problemet är den här bloggen för dig.

Java kräver att tredjeparts- och användardefinierade klasser finns på kommandoradens "–classpath ” när JVM startas. `hadoop` wrapper-skalskriptet gör exakt detta för dig genom att bygga klassvägen från kärnbiblioteken som finns i /usr/lib/hadoop-0.20/ och /usr/lib/hadoop-0.20/lib/ kataloger. Men med MapReduce exekveras ditt jobbs uppgiftsförsök på fjärrnoder. Hur berättar du för en fjärrdator att inkludera tredjeparts- och användardefinierade klasser?

MapReduce-jobb exekveras i separata JVMs på TaskTrackers och ibland behöver du använda tredjepartsbibliotek i kartan/minska uppgiftsförsöken. Till exempel kanske du vill komma åt HBase från dina kartuppgifter. Ett sätt att göra detta är att paketera varje klass som används i den inlämningsbara JAR. Du måste packa upp originalet hbase-.jar och packa om alla klasser i din inlämningsbara Hadoop-burk. Inte bra. Gör inte så här:Problemen med versionskompatibilitet kommer att bita på dig förr eller senare.

Det finns bättre sätt att göra detsamma genom att antingen placera din jar i distribuerad cache eller installera hela JAR på Hadoop-noderna och berätta för TaskTrackers om deras plats.

1. Inkludera JAR i "-libjars ” kommandoradsalternativ för kommandot `hadoop jar …`. Burken kommer att placeras i distribuerad cache och kommer att göras tillgänglig för alla jobbets uppgiftsförsök. Mer specifikt hittar du JAR i en av ${mapred.local.dir}/taskTracker/archive/${user.name}/distcache/… underkataloger på lokala noder. Fördelen med den distribuerade cachen är att din jar kanske fortfarande finns där vid nästa programkörning (åtminstone i teorin:filerna ska bara kastas ut ur den distribuerade cachen när de överskrider den mjuka gränsen som definieras av local.cachen) .size konfigurationsvariabel, är standard på 10 GB, men din faktiska körsträcka kan variera särskilt med de senaste säkerhetsförbättringarna). Hadoop håller reda på ändringarna i de distribuerade cachefilerna genom att undersöka deras modifieringstidsstämpel.

*Uppdatering till inlägg:Observera att objekt 2 och 3 nedan är utfasade från och med CDH4 och kommer inte längre att stödjas från och med CDH5.

2. Inkludera den refererade JAR i underkatalogen lib för den inlämningsbara JAR:Ett MapReduce-jobb packar upp JAR från denna underkatalog till ${mapred.local.dir}/taskTracker/${user.name}/jobcache/$ jobid/burkar på TaskTracker-noderna och peka dina uppgifter till den här katalogen för att göra JAR tillgänglig för din kod. Om JAR:erna är små, byts ofta och är jobbspecifika, är detta den föredragna metoden.

3. Slutligen kan du installera JAR på klusternoderna. Det enklaste sättet är att placera JAR i $HADOOP_HOME/lib katalog eftersom allt från denna katalog ingår när en Hadoop-demon startar. Men eftersom du vet att endast TaskTrackers kommer att behöva dessa nya JAR, är ett bättre sätt att ändra alternativet HADOOP_TASKTRACKER_OPTS i konfigurationsfilen hadoop-env.sh. Denna metod är att föredra om JAR är knuten till koden som körs på noderna, som HBase.

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

Starta om TastTrackers när du är klar. Glöm inte att uppdatera burken när den underliggande programvaran ändras.

Alla ovanstående alternativ påverkar endast koden som körs på de distribuerade noderna. Om din kod som startar Hadoop-jobbet använder samma bibliotek måste du även inkludera JAR i miljövariabeln HADOOP_CLASSPATH:

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

Observera att från och med Java 1.6 classpath kan peka på kataloger som "/path/to/your/jars/* ” som hämtar alla JAR från den givna katalogen.

Samma vägledande principer gäller för inbyggda kodbibliotek som måste köras på noderna (JNI eller C++ pipes). Du kan lägga dem i distribuerad cache med "-filer "-alternativ, inkludera dem i arkivfiler som anges med "-arkiv ” eller installera dem på klusternoderna. Om den dynamiska bibliotekslänken är korrekt konfigurerad bör den ursprungliga koden göras tillgänglig för dina uppgiftsförsök. Du kan också ändra miljön för jobbets pågående uppgiftsförsök explicit genom att ange JAVA_LIBRARY_PATH eller LD_LIBRARY_PATH variabler:

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

  1. Hur man implementerar MongoDB kapslad $elemMatch Query i C#

  2. Hur man skapar användare i mongodb med docker-compose

  3. MongoDB $tan

  4. Introduktion till Redis Cluster Sharding – Fördelar, begränsningar, distribution och klientanslutningar