hadoop运行随记2

 Exiting due to:java.lang.OutOfMemoryError: Resource temporarily unavailable in tsStartJavaThread (lifecycle.c:1096).
Java heap 1000M reserved, 64M committed
Paged memory=18014398494602108K/53350396K.
Your Java heap size might be set too high.
Try to reduce the Java heap size using -Xmx:<size> (e.g
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:640)
        at org.apache.hadoop.hdfs.server.datanode.DataXceiverServer.run(DataXceiverServer.java:133)

        at java.lang.Thread.run(Thread.java:662)


简单地从报错信息来看,有两个点:

第一:降低堆的最大值设置

第二:报错信息是OutOfMemoryError,说明有内存溢出

按照一般解决方式就是内存不够,咱就增加最大内存值,

但是很有趣的是,首先是报错OutOfMemory表明内存不够用了,但后面的日志信息是说需要降低-Xmx的设置,是不是有点自相矛盾。



这是查看相关进程运行状态:
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                         
23480 hadoop    20   0 6606m 461m 4120 S 10.3  1.4   1:54.05 java                                                                                            
27956 hadoop    20   0 6093m 356m 4120 S 57.9  1.1   0:45.82 java                                                                                            
29151 hadoop    20   0 6093m 356m 4116 S 56.6  1.1   0:35.76 java                                                                                            
28735 hadoop    20   0 6093m 355m 4116 S 70.8  1.1   0:40.63 java                                                                                            
29635 hadoop    20   0 6093m 323m 3884 S 218.4  1.0   0:08.46 java                                                                                           
15537 hadoop    20   0 14.2g 175m 4272 S  0.7  0.5  32:57.77 java                                                                                            
15692 hadoop    20   0 10.8g 151m 4276 S  8.6  0.5  11:18.66 java    
         
                                                                             
27149 hadoop    20   0 7504m 142m 4124 S  8.9  0.4   0:23.19 java   


在此红色字体里VIRT的值太大了,达到了14.2g。还在查明原因中……………

经检查源码发现,是创建Daemon线程太多导致。导致的原因:

第一是最近集群内的节点有一定数量的机器被拿去支持起来的应用

第二是目前有一台机器的节点硬盘出现了问题

第三是出现以上两个情况后,这些节点在撤出集群的时候没有做数据均衡的操作

基于以上的原因,导致了Daemon创建很多,因为这样就是更多的block需要进行网络传输获取


部分源码如下:

 public void run() {

    while (datanode.shouldRun) {

      try {

        Socket s = ss.accept();

        s.setTcpNoDelay(true);

        new Daemon(datanode.threadGroup

            new DataXceiver(s, datanode, this)).start();

      } catch (SocketTimeoutException ignored) {

        // wake up to see if should continue to run

      } catch (AsynchronousCloseException ace) {

          LOG.warn(datanode.dnRegistration +":DataXceiveServer:"

                  + StringUtils.stringifyException(ace));

          datanode.shouldRun =false;

      } catch (IOException ie) {

        LOG.warn(datanode.dnRegistration + ":DataXceiveServer: IOException due to:"

                                 + StringUtils.stringifyException(ie));

      } catch (Throwable te) {

        LOG.error(datanode.dnRegistration + ":DataXceiveServer: Exiting due to:" 

                                 + StringUtils.stringifyException(te));

        datanode.shouldRun =false;

      }

    }

    try {

      ss.close();

    } catch (IOException ie) {

      LOG.warn(datanode.dnRegistration + ":DataXceiveServer: Close exception due to: "

                               + StringUtils.stringifyException(ie));

    }

    LOG.info("Exiting DataXceiveServer");

  }


在第六行里代码中每次datanode的处理都会创建一个线程对应一个socket连接。


另外补充说明下,当节点一次性退出太多;硬盘出现问题;集群的规模不够大的时候,会偶尔出现以上这样的问题。

但是在退出很多节点前,做数据均衡的时间很漫长(随着集群的规模越大越慢)

这样就很纠结了。

所以尽量避免这样情况出现(不过在实际的工作当中,有时候难免会碰到的,大家都懂)


为了检验数据均衡后是否还会带来此问题

我还是做了下数据均衡操作,运行时间长达12个小时(9TB的数据、7个节点),不知道是否正常(是否还是需要在IO上面多做文章)

 

目前境况是:还是会出现此问题,正在进行相关参数的调整中……………………

经过两天的紧张的测试后,问题解决了,解决方法有二:

第一:降低Xmx的值,我设置成512M就没有问题

第二:/etc/security/limit.conf文件没有设置nproc的限制


所以建议用第二种方式。

已经是第二次被调试参数折腾了惨目忍睹啊!!!!!


你可能感兴趣的:(hadoop运行随记2)