Hadoop RPC服务器不会停止

时间:2012-12-17 20:15:43

标签: process hadoop ipc rpc

我正在尝试使用Hadoop IPC在它们之间创建一个简单的父子进程。事实证明,程序执行并打印结果,但它不会退出。这是它的代码。

interface Protocol extends VersionedProtocol{
  public static final long versionID = 1L;
  IntWritable getInput();
}

public final class JavaProcess implements Protocol{
  Server server;

  public JavaProcess() {
  String rpcAddr = "localhost";
  int rpcPort = 8989;
  Configuration conf = new Configuration();
  try {
    server = RPC.getServer(this, rpcAddr, rpcPort, conf);
    server.start();

  } catch (IOException e) {
    e.printStackTrace();
  }
}

public int exec(Class klass) throws IOException,InterruptedException {
  String javaHome = System.getProperty("java.home");
  String javaBin = javaHome +
      File.separator + "bin" +
      File.separator + "java";
  String classpath = System.getProperty("java.class.path");
  String className = klass.getCanonicalName();

  ProcessBuilder builder = new ProcessBuilder(
      javaBin, "-cp", classpath, className);

  Process process = builder.start();
  int exit_code = process.waitFor();
  server.stop();

  System.out.println("completed process");
  return exit_code;
}

public static void main(String...args) throws IOException, InterruptedException{
  int status = new JavaProcess().exec(JavaProcessChild.class);
  System.out.println(status);
}

@Override
public IntWritable getInput() {
  return new IntWritable(10);
}

@Override
public long getProtocolVersion(String paramString, long paramLong)
    throws IOException {
  return Protocol.versionID;
 }
}

这是子进程类。但是我已经意识到这是由于服务器端的RPC.getServer()导致它的罪魁祸首。是一些已知的hadoop bug,还是我遗漏了什么?

public class JavaProcessChild{

  public static void main(String...args){
    Protocol umbilical = null;
    try {
       Configuration defaultConf = new Configuration();
       InetSocketAddress addr = new InetSocketAddress("localhost", 8989);
       umbilical = (Protocol) RPC.waitForProxy(Protocol.class, Protocol.versionID,
            addr, defaultConf);
       IntWritable input = umbilical.getInput();

       JavaProcessChild my = new JavaProcessChild();

      if(input!=null && input.equals(new IntWritable(10))){
        Thread.sleep(10000);
      }
      else{
        Thread.sleep(1000);
      }
    } catch (Throwable e) {
      e.printStackTrace();
   } finally{
      if(umbilical != null){
        RPC.stopProxy(umbilical);
      }
  }
}
}

1 个答案:

答案 0 :(得分:1)

我们通过邮件对其进行了整理。但我只想在这里为公众提供两分钱:

因此,那里没有死亡的线程(因此不让主线程完成)是org.apache.hadoop.ipc.Server$Reader。 原因是readSelector.select();的实现不可中断。如果仔细查看调试器或threaddump,即使主线程已经被清理,它也会永远等待该调用。

两种可能的修复方法:

  • 让读者线程成为一个守护者(不是很酷,因为选择器 将无法正确清理,但过程将结束)
  • 在中断线程池时从外部显式关闭“readSelector”

然而,这是Hadoop中的一个错误,我没有时间浏览JIRA。也许这已经解决了,在YARN中,无论如何旧的IPC被protobuf和thrift取代。

顺便说一句BTW也是平台依赖于选择器的实现,我在debian / windows系统上观察了这些僵尸,但没有在redhat / solaris上观察。

如果有人对Hadoop 1.0的补丁感兴趣,请给我发电子邮件。我将在不久的将来理清JIRA错误,并在此处编辑更多信息。 (也许这在任何时候都是固定的。)