私は単一マシンのローカルのみのセットアップでhadoopを実行しており、Eclipseでマッパーとリデューサーをデバッグするための優れた痛みのない方法を探しています。 Eclipseはmapreduceタスクの実行に問題はありません。ただし、デバッグに行くと、次のエラーが発生します。
12/03/28 14:03:23警告mapred.JobClient:ジョブjarファイルが設定されていません。ユーザークラスが見つからない可能性があります。 JobConf(Class)またはJobConf#setJar(String)を参照してください。
さて、私はいくつかの研究をします。どうやら、Eclipseのリモートデバッグ機能を使用して、これをhadoop-env.sh
に追加する必要があります。
-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5000
私はそれを行い、Eclipseでコードをステップスルーできます。唯一の問題は、「suspend = y」のため、コマンドラインから「hadoop」コマンドを使用してジョブキューを確認するなどの操作を実行できないことです。ハングします。デバッガーが接続するのを待っているので、想像しています。また、おそらく同じ理由で、このモードでは「hbaseShell」を実行できません。
したがって、基本的に、「デバッグモード」と「通常モード」の間を行ったり来たりしたい場合は、hadoop-env.sh
を更新してマシンを再起動する必要があります。大きな痛み。だから私はいくつかの質問があります:
Eclipseでmapreduceジョブをデバッグする簡単な方法はありますか?
どうしてEclipseはmapreduceジョブをうまく実行できるのですか?デバッグにはリモートデバッグを使用する必要がありますか?
Mapreduceジョブにリモートデバッグを使用するようにhadoopに指示する方法はありますが、他のすべてのタスクには通常モードで動作しますか? ( "hadoop queue"または "hbase Shell"など)。
マシンを再起動せずにhadoop-env.sh
構成を切り替える簡単な方法はありますか? hadoop-env.shはデフォルトでは実行できません。
これはより一般的な質問です。ローカルのみのモードでHadoopを実行すると、正確に何が起こっているのでしょうか。 「常にオン」でHadoopジョブを実行しているプロセスは私のマシンにありますか?または、hadoopは、コマンドラインから「hadoop」コマンドを実行した場合にのみ機能しますか? Eclipseからmapreduceジョブを実行すると、Eclipseは何をしますか?プロジェクトを機能させるには、hadoop-core
でpom.xml
を参照する必要がありました。 Eclipseはインストールされたhadoopインスタンスにジョブを送信していますか、それともMavenキャッシュのhadoop-core-1.0.0.jar
からすべてを実行していますか?
これが私のメインクラスです:
public class Main {
public static void main(String[] args) throws Exception {
Job job = new Job();
job.setJarByClass(Main.class);
job.setJobName("FirstStage");
FileInputFormat.addInputPath(job, new Path("/home/sangfroid/project/in"));
FileOutputFormat.setOutputPath(job, new Path("/home/sangfroid/project/out"));
job.setMapperClass(FirstStageMapper.class);
job.setReducerClass(FirstStageReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
/bin/hadoop
(hadoop-env.sh
)スクリプトに変更を加えます。どのコマンドが実行されたかを確認してください。コマンドがjar
の場合は、リモートデバッグ構成のみを追加します。
if [ "$COMMAND" = "jar" ] ; then
exec "$Java" -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8999 $Java_HEAP_MAX $HADOOP_OPTS $CLASS "$@"
else
exec "$Java" $Java_HEAP_MAX $HADOOP_OPTS $CLASS "$@"
fi
EclipseでHadoopをデバッグできる唯一の方法は、ローカルモードでHadoopを実行することです。その理由は、各マップリデュースタスクが独自のJVMで実行され、ローカルモードでHadoopを使用しない場合、Eclipseはデバッグできません。
Hadoopをローカルモードに設定すると、hdfs API(デフォルト)を使用する代わりに、Hadoopファイルシステムがfile:///
に変更されます。したがって、hadoop fs -ls
の実行はhdfsコマンドではなく、ローカルディレクトリへのパスであるhadoop fs -ls file:///
の多くになります。 JobTrackerまたはNameNodeは実行されません。
これらのブログ投稿は役立つかもしれません:
Jumbuneのデバッガーは、最小限の労力でこれらすべてを実行します。
デバッガーは、MapReduceジョブのコードレベルの制御フロー統計を提供します。
ユーザーは、正規表現検証または独自のユーザー定義検証クラスを適用できます。適用された検証に従って、FlowDebuggerはマッパーとレデューサーのデータフローをそれぞれチェックします。
また、入力レコードのフローがジョブレベル、MRレベル、およびインスタンスレベルで表示される包括的なテーブル/チャートビューも提供します。一致しないキー/値は、ジョブ実行結果の誤ったキー/値データの数を表します。デバッガーはコードにドリルダウンして、ループや条件if、else-ifなどのさまざまなカウンターのデータフローを調べます。
Jumbuneはオープンソースであり、www.jumbune.orgおよび https://github.com/impetus-opensource/jumbune で入手できます。
推奨されるMRUnitの他に、Eclipseでデバッグするのも好きです。メインプログラムがあります。構成をインスタンス化し、MapReduceジョブを直接実行します。標準のEclipseDebug構成でデバッグするだけです。 mvn仕様にHadoopjarを含めているので、クラスパスにすべてのHadoop自体があり、インストールされているHadoopに対して実行する必要はありません。私はいつもローカルディレクトリの小さなデータセットでテストして、物事を簡単にします。構成のデフォルトは、スタンドアロンのHadoopとして動作します(ファイルシステムが利用可能です)
また、MRUnitを使用したユニットテストでデバッグするのも好きです。これを承認テストと組み合わせて使用します。これにより、Map Reduceプロセスを簡単に視覚化し、失敗したシナリオを簡単に渡すことができます。また、Eclipseからシームレスに実行されます。
例えば:
HadoopApprovals.verifyMapReduce(new WordCountMapper(),
new WordCountReducer(), 0, "cat cat dog");
出力を生成します:
[cat cat dog]
-> maps via WordCountMapper to ->
(cat, 1)
(cat, 1)
(dog, 1)
-> reduces via WordCountReducer to ->
(cat, 2)
(dog, 1)
ここにプロセスに関するビデオがあります: http://t.co/leExFVrf
Hadoopの内部Javaコマンドへの引数の追加は、HADOOP_OPTS環境変数を介して実行できます。
export HADOOP_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=5005,suspend=y"