0

Hadoop IPCを使用して、それらの間に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バグですか、それとも何かが足りませんか?

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);
      }
  }
}
}
4

1 に答える 1

1

それをメールで整理しました。しかし、私はここで私の2セントを一般に提供したいと思います。

したがって、そこで死んでいない(したがってメインスレッドを終了させて​​いない)スレッドはorg.apache.hadoop.ipc.Server$Readerです。その理由は、の実装がreadSelector.select();中断できないためです。デバッガーまたはスレッドダンプをよく見ると、メインスレッドが既にクリーンアップされている場合でも、その呼び出しを永久に待機しています。

2つの可能な修正:

  • リーダースレッドをデーモンにします(セレクターが適切にクリーンアップされないため、それほどクールではありませんが、プロセスは終了します)
  • スレッドプールに割り込むときに、外部から「readSelector」を明示的に閉じます

ただし、これはHadoopのバグであり、JIRAを調べる時間がありません。たぶん、これはすでに修正されています。YARNでは、古いIPCがprotobufに置き換えられ、とにかく節約されます。

ところで、これはセレクターの実装に依存するプラットフォームでもあります。私はこれらのゾンビをdebian / windowsシステムで観察しましたが、redhat/solarisでは観察しませんでした。

Hadoop 1.0のパッチに興味がある人がいたら、私にメールしてください。近い将来、JIRAのバグを整理し、ここで詳細情報を編集します。(多分これはとにかくその間に修正されます)。

于 2012-12-18T11:32:20.050 に答える