admin管理员组

文章数量:1608627

问题

  客户现场使用公司的kettle工具往hadoop写数据时报错:
  Connection timed out: no futher infomation

报错截图

原因分析

  使用debug模式运行,后台日志中打印了将数据写入hadoop操作系统时,目标DataNode的ip(这个ip是通过hadoop客户端api访问NameNode得到)。但是这个ip并不能访问通,因为hadoop客户端配置的ip是hadoop集群节点的映射ip,集群节点的真实内网ip禁止访问。但是客户端和服务端的hosts文件中域名是一致的,通过域名访问NameNode没有问题,问题就出在,hadoop客户端api返回的要求写入的block所属的地址是个ip,而不是域名。
  跟踪错误堆栈,发现DFSOutputStream类的如下代码:

  static Socket createSocketForPipeline(final DatanodeInfo first,
      final int length, final DFSClient client) throws IOException {
    final String dnAddr = first.getXferAddr(
        client.getConf().connectToDnViaHostname);
    if (DFSClient.LOG.isDebugEnabled()) {
      DFSClient.LOG.debug("Connecting to datanode " + dnAddr);
    }
    final InetSocketAddress isa = NetUtils.createSocketAddr(dnAddr);
    final Socket sock = client.socketFactory.createSocket();
    final int timeout = client.getDatanodeReadTimeout(length);
    NetUtils.connect(sock, isa, client.getRandomLocalInterfaceAddr(), client.getConf().socketTimeout);
    sock.setSoTimeout(timeout);
    sock.setSendBufferSize(HdfsConstants.DEFAULT_DATA_SOCKET_SIZE);
    if(DFSClient.LOG.isDebugEnabled()) {
      DFSClient.LOG.debug("Send buf size " + sock.getSendBufferSize());
    }
    return sock;
  }

  createSocketForPipeline方法中第一行就是获取DataNode的地址,getXferAddr方法的参数如果传入true就是返回一个域名,false就是返回一个ip。通过代码发现,此处是一个hdfs的配置,属性为dfs.client.use.datanode.hostname。于是我们在客户端的hdfs-site.xml配置文件中增加如下配置后问题解决:

<property>
    <name>dfs.client.use.datanode.hostname</name>
    <value>true</value>
    <description>only cofig in clients</description>
 </property>

本文标签: timedConnectioninfomationfuther