私の大学のいくつかのマシン (Linux Fedora 25 を実行しているすべてのマシン) に Hadoop YARN クラスターをセットアップしています。YARN で mapreduce ジョブを実行しているときに、別のプログラムに対して行った呼び出しからの出力を受け取ることができません。興味深いことに、(mapred-site.xml で構成された) ジョブをローカルで実行すると、プログラムを呼び出してその出力を受け取る方法は問題なく機能します。以下は、最初のマップ タスクでインスタンス化されて使用される executeShellCommand クラスです。
public class ExecuteShellCommand {
public String executeCommand(String command) {
StringBuffer output = new StringBuffer();
Process p;
try {
String [] args = command.split(" ");
String cmd = args[0];
ProcessBuilder pb = new ProcessBuilder().command(cmd, args[1], args[2], args[3], args[4], args[5], args[6], args[7]).directory(new File("path to executable"));
p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
p.waitFor();
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
return e.toString();
}
return output.toString();
}
}
私が確認したこと:
1) 必要なすべてのファイル/ディレクトリに対して権限が適切に設定されている
2) マップタスクは現在のユーザー (私) として実行されるため、不正アクセスの問題はありません
3) ファイルが見つからないという例外を受け取っていないため、呼び出しているプログラムへのパスは正しい
4) プロセス p の入出力ストリームを確認しました (入力ストリームは java.lang.UNIXProcess$ProcessPipeInputStream@1000e80 として設定され、出力ストリームは null です)。
5) 使用する必要のあるプログラムを呼び出す代わりに、単純な「echo」コマンドを試しましたが、その出力も受け取ることができませんでした。
6)私も使ってみました
p = Runtime.getRuntime().exec("myCommand")
ただし、結果は同じです (出力は受信されません)
既に述べたように、ジョブをローカルで実行すると、executeCommand メソッドが完全に機能し、呼び出したプログラムからの出力が返されます。問題が発生するのは YARN だけです。正しいバッファから読み込んでいない、または ProcessBuilder に発行されたコマンドが実際に実行されていないことが原因で発生した問題を感じています。ここで何が起こっているのかをデバッグする方法については非常に困惑しています。ヒントがあれば大歓迎です!