我在大学的一些机器上安装了hadoopYarn集群(所有机器都运行linuxfedora25)。在yarn中运行mapreduce作业时,我无法从对单独程序的调用接收输出。有趣的是,如果我在本地运行我的作业(在mapred site.xml中配置),我调用程序并接收其输出的方法就可以正常工作。下面是我的executeshellcommand类,它被示例化并用于我的第一个Map任务。
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) Map任务以当前用户(me)身份运行,因此不会出现非法访问问题
3) 我没有收到文件未找到异常,因此我调用的程序的路径是正确的
4) 检查了进程p的输入/输出流(输入流设置为java.lang)。unixprocess$processpipeinputstream@1000e80,输出流为空)
5) 我没有调用需要使用的程序,而是尝试了一个简单的“echo”命令,但也无法接收该输出。
6) 我也试过使用
p = Runtime.getRuntime().exec("myCommand")
但是结果是一样的(没有收到输出)
正如我已经提到的,当我在本地运行一个作业时,我的executecommand方法可以完美地运行,并返回我调用的程序的输出。只有在Yarn中才会出现问题。我有一种感觉,要么是因为没有从正确的缓冲区读取,要么是因为向processbuilder发出的命令从未实际执行。我很困惑,如何调试什么是在这里发生的,任何提示将不胜感激!
1条答案
按热度按时间zu0ti5jz1#
在尝试了几个小时的各种解决方案之后,我找到了如何从processbuilder生成的进程中获取错误流的方法。结果是,当我为进程设置工作目录时,我忘记了更新传递给它的一个参数的路径。哦!!!