「私のライブラリはクラスパスにありますが、MapReduceジョブでClass Not Found例外が発生します」–この問題が発生した場合は、このブログが役に立ちます。
Javaでは、サードパーティおよびユーザー定義のクラスがコマンドラインの「– classpath 」にある必要があります JVMが起動されたときの「」オプション。 `hadoop`ラッパーシェルスクリプトは、 /usr/lib/hadoop-0.20/にあるコアライブラリからクラスパスを構築することで、まさにこれを実現します。 および/usr/lib/hadoop-0.20/lib/ ディレクトリ。ただし、MapReduceを使用すると、ジョブのタスク試行はリモートノードで実行されます。リモートマシンにサードパーティおよびユーザー定義のクラスを含めるようにどのように指示しますか?
MapReduceジョブはTaskTracker上の別々のJVMで実行され、map/reduceタスクの試行でサードパーティのライブラリを使用する必要がある場合があります。たとえば、マップタスク内からHBaseにアクセスしたい場合があります。これを行う1つの方法は、送信可能なJARで使用されるすべてのクラスをパッケージ化することです。元のhbase-.jar
を解凍する必要があります 送信可能なHadoopjarにすべてのクラスを再パッケージ化します。良くない。これを行わないでください。バージョンの互換性の問題により、遅かれ早かれ問題が発生します。
jarを分散キャッシュに配置するか、JAR全体をHadoopノードにインストールしてTaskTrackerにその場所を通知することで、同じことを行うためのより良い方法があります。
1.「-libjars」にJARを含めます ”`hadoopjar…`コマンドのコマンドラインオプション。 jarは分散キャッシュに配置され、ジョブのすべてのタスク試行で使用できるようになります。具体的には、JARは $ {mapred.local.dir} / taskTracker / archive / $ {user.name} /distcache/…のいずれかにあります。 ローカルノードのサブディレクトリ。分散キャッシュの利点は、次のプログラム実行時にjarがまだ存在する可能性があることです(少なくとも理論的には、ファイルは、 local.cacheで定義されたソフト制限を超えた場合にのみ分散キャッシュから追い出される必要があります)。 .size 構成変数、デフォルトは10GBですが、実際のマイレージは、特に最新のセキュリティ拡張機能によって異なる場合があります)。 Hadoopは、変更のタイムスタンプを調べることにより、分散キャッシュファイルへの変更を追跡します。
*投稿の更新:以下の項目2および3は、CDH4以降では非推奨であり、CDH5以降ではサポートされなくなることに注意してください。
2.送信可能なJARのlibサブディレクトリに参照されたJARを含めます。MapReduceジョブは、このサブディレクトリから $ {mapred.local.dir} / taskTracker / $ {user.name} / jobcache/$にJARを解凍します。 jobid / jars TaskTrackerノードで、タスクをこのディレクトリにポイントして、JARをコードで使用できるようにします。 JARが小さく、頻繁に変更され、ジョブ固有である場合は、これが推奨される方法です。
3.最後に、JARをクラスターノードにインストールできます。最も簡単な方法は、JARを $ HADOOP_HOME / libに配置することです。 Hadoopデーモンの起動時に、このディレクトリのすべてが含まれるため、ディレクトリ。ただし、これらの新しいJARが必要になるのはTaskTrackerのみであることがわかっているため、hadoop-env.sh構成ファイルのHADOOP_TASKTRACKER_OPTSオプションを変更することをお勧めします。この方法は、JARがHBaseなどのノードで実行されているコードに関連付けられている場合に推奨されます。
HADOOP_TASKTRACKER_OPTS="-classpath<colon-separated-paths-to-your-jars>"
完了したら、TastTrackersを再起動します。基盤となるソフトウェアが変更されたときにjarを更新することを忘れないでください。
上記のすべてのオプションは、分散ノードで実行されているコードにのみ影響します。 Hadoopジョブを起動するコードが同じライブラリを使用している場合は、JARをHADOOP_CLASSPATH環境変数にも含める必要があります。
HADOOP_CLASSPATH="<colon-separated-paths-to-your-jars>"
Java 1.6以降では、クラスパスは「 / path / to / your / jars / *」のようなディレクトリを指すことができることに注意してください。 」は、指定されたディレクトリからすべてのJARを取得します。
同じガイド原則が、ノード(JNIまたはC ++パイプ)で実行する必要のあるネイティブコードライブラリにも適用されます。 「-ファイル」を使用して、それらを分散キャッシュに入れることができます。 」オプションは、「 -archives」で指定されたアーカイブファイルに含めます。 」オプション、またはクラスターノードにインストールします。ダイナミックライブラリリンカーが適切に構成されている場合は、タスクの試行でネイティブコードを使用できるようにする必要があります。 JAVA_LIBRARY_PATH変数またはLD_LIBRARY_PATH変数を指定することにより、ジョブの実行中のタスク試行の環境を明示的に変更することもできます。
hadoop jar <your jar> [main class] -D mapred.child.env="LD_LIBRARY_PATH=/path/to/your/libs" ...