Hadoop RPC 服务器不会停止

Posted

技术标签:

【中文标题】Hadoop RPC 服务器不会停止【英文标题】:Hadoop RPC server doesn't stop 【发布时间】:2012-12-17 20:15:42 【问题描述】:

我试图使用 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);
      
  


【问题讨论】:

【参考方案1】:

我们通过邮件解决了这个问题。但我只想在这里为公众提供我的两分钱:

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

两个可能的修复:

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

但是,这是 Hadoop 中的一个错误,我没有时间查看 JIRA。也许这已经修复了,在 YARN 中,旧的 IPC 已被 protobuf 和 thrift 取代。

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

如果有人对 Hadoop 1.0 的补丁感兴趣,请给我发电子邮件。我将在不久的将来整理 JIRA 错误,并在此处编辑此内容以提供更多信息。 (也许这同时已经修复了)。

【讨论】:

以上是关于Hadoop RPC 服务器不会停止的主要内容,如果未能解决你的问题,请参考以下文章

Hadoop RPC机制中Server类的实现:基于Java NIO

Hadoop RPC机制中Server类的实现:基于Java NIO

Hadoop RPC机制中Server类的实现:基于Java NIO

Hadoop RPC简单实例

Hadoop RPC通信

利用Hadoop提供的RPC API实现简单的RPC程序