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的限制
所以建议用第二种方式。
已经是第二次被调试参数折腾了惨目忍睹啊!!!!!