龙空技术网

0599-5.14.4-HDFS出现大量BrokenPipe异常处理

Hadoop实操 371

前言:

此刻我们对“java断开的管道”大约比较看重,你们都想要学习一些“java断开的管道”的相关知识。那么小编在网摘上搜集了一些对于“java断开的管道””的相关文章,希望兄弟们能喜欢,姐妹们快快来学习一下吧!

作者:李继武&陶攀龙

1.故障描述

在HBase和Hive集群中HDFS的DataNode节点均有大量的异常日志,详细日志信息如下:

2019-02-25 17:02:02,153 ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: BlockSender.sendChunks() exception: java.io.IOException: 断开的管道 at sun.nio.ch.FileChannelImpl.transferTo0(Native Method) at sun.nio.ch.FileChannelImpl.transferToDirectlyInternal(FileChannelImpl.java:416) at sun.nio.ch.FileChannelImpl.transferToDirectly(FileChannelImpl.java:481) at sun.nio.ch.FileChannelImpl.transferTo(FileChannelImpl.java:596) at org.apache.hadoop.net.SocketOutputStream.transferToFully(SocketOutputStream.java:223)...

主要以Hive集群分析为主,该集群中有hive01和hive02两个节点即是管理节点也是数据节点,这两个节点上出现了大量的“Broken Pipe”异常日志

2.故障分析阶段(平台层面)

通过提供给Cloudera售后的HDFS日志、lsof日志以及其它搜集的日志,在初步分析后反应出来的现象HBase出现性能问题是由于底层的HDFS不稳定导致。在HDFS的DataNode节点有大量的“Broken Pipe”异常,由于大量的Broken Pipe导致DataNode读写Block时重试从而导致基于HDFS的HBase等应用会出现性能下降的问题。

售后提出协调系统管理员分析系统层面的问题,在OS层面与旧集群未做任何变动,系统的参数及Hadoop的基本运行环境均与旧集群一致。

1. 通过分析Hive集群发现 NameNode GC频繁且耗时,如下图所示

将NameNode的Java heap大小从6GB调整至10GB

增加NameNode的Heap大小后通过jstat命令和CM监控界面进行监控,看到NameNode的GC得到缓解

sudo -u hdfs /usr/java/jdk1.7.0_80/bin/jstat -gcutil 180080 1000 1000

通过调整NameNode Heap大小,解决了NameNode频繁且耗时的GC问题,但并没有解决DataNode服务的“Broken Pipe”问题。

2. 期间通过调整hive01节点DataNode服务的日志未DEBUG级别,重启DataNode服务后分析输出的Debug日志

日志能够输出DN节点操作每个Block的大小等一些详细信息,但对于抛出的异常堆栈信息还是不够详细,无法通过堆栈信息定位到DN在操作哪个Block时输出的异常,无法很好的跟中异常异常日志所连接的TCP端口号及对应的DN节点。

3. 在分析集群的配置参数时,发现集群的几个数据节点内存使用都过高

期间怀疑是集群资源使用过高,导致DataNode节点读写数据慢导致,通过将角色分组的方式将hive01和hive02节点划分到一个独立的角色组,并降低Yarn资源的内存使用至48GB。通过重启NodeManager服务观察DataNode节点任然出现大量“Broken Pipe”异常。

4. 在查看OS的关于tcp的内核参数时,发现多个关于tcp连接有关的参数配置,怀疑内核参数配置导致TCP连接中断,通过将sysctl.conf配置文件中的部分tcp内核配置屏蔽

原始配置如下:

修改后配置如下:

经过观察DataNode服务仍然有大量的“Broken Pipe”异常。

5. 通过分析HDFS的源码异常信息抛出的代码段,发现DN服务在读取当前节点的Block时,将Block发送至其他DN节点时,由于TCP连接中断导致抛出“Broken Pipe”异常信息

通过DataXceiverServer服务判断当前DatNode启动的xceiver线程数是否达到设置的最大值(dfs.datanode.max.transfer.threads,默认4096)如果没有达到最大值则启动线程

初始化initDataXceiver时指定的sockewriteTimeOut值,该值对于HDFS的

dfs.datanode.socket.write.timeout 默认8*60*1000dfs.client.socket-timeout 默认60 * 1000dfs.datanode.socket.reuse.keepalive 默认4000dfs.datanode.transfer.socket.recv.buffer.size 默认值131072

3.故障分析阶段(网络层面)

1. 从系统网卡的信息上看,网卡存在大量丢包的情况,并且出现”Broken Pipe”异常的节点上的丢包数要明显多于未出现该异常的节点,怀疑可能是网络配置问题。

出现”Broken Pipe”异常的hive01和hive02节点:

未出现”Broken Pipe”异常的hive03和hive04节点:

2. 使用tcpdump工具从报错节点上抓取数据包信息,使用wireshark进行分析,在抓出的数据包中出现如下一些错误,运维同事初步怀疑是否是做的bond网卡有问题。

3. 根据运维同事介绍,目前hive集群与hbase集群的网络架构如下

每一台节点都通过两个万兆物理网卡实现高可用,本次测试通过将hive集群上每台节点上的一个网卡接口禁用,使用单网卡连接相同的交换机进行通信,测试效果。在未测试前,hive1/2节点存在”Broken Pipe”问题,而hive3/4节点不存在这个问题。

首先,测试hive1/2/3/4节点与A交换机断开之后的效果,即

此时,hive1/2/3/4节点仅通过一个网卡与交换机B通信,在这种状态运行一个小时,统计结果:hive1/2仍存在”Broken Pipe”异常,在这一小时内,单节点数量达到15000个,而此前5个小时内该数量最大在单节点每小时5000个,不排除在这一小时内作业突然增多情况,hive3/4仍没有异常,所有节点都没有出现其他异常。

测试hive1/2/3/4节点与B交换机断开之后的效果,即

此时,hive1/2/3/4节点仅通过一个网卡与交换机A通信,在这种状态运行一个小时,统计结果:hive1/2仍存在”Broken Pipe”异常,在这一小时内,单节点数量为7000个,hive3/4仍然没有”Broken Pipe”异常,从更换网卡之后,所有节点均出现了新的异常:EOFexception,每个节点都保持在每分钟有多条该报警记录。

在做如上两个测试的过程当中,平台组件均没有重启。

该测试总结:根据cdh平台的要求,一个万兆网卡即可满足平台需求,理论上bond的网卡在始终保持有一个网卡处于可用状态的时候,应用层不应当感受到网卡切换的变化,即在更换网卡之后应用不应当出现新的错误和原异常显著增多的情况,所以这更倾向于网络或者OS底层问题。

4. 在ifconfig中网卡出现dropped的原因:网卡已经接受到数据包,在从网卡缓存传输到系统内存中时发生丢失;DELL厂商建议增大网卡缓存大小,增加到2048,在终端执行该操作后重启网卡,异常仍然没有消失。

5. 解除所有节点的bond网卡,所有数据节点都使用单网卡模式,取消网卡之后重启网卡,观察一段时间,发现报错仍然没有消失,报错的仍然是hive1/2,hive3/4正常。

6. Hive集群中报错的两个节点为hive1/2,不报错的为hive3/4,而hive1/2上组件角色要比hive3/4多,测试是否是因为服务多负载重引起该异常,将hive2上的NameNode,Hiveserver2,HiveMetastore,ResourceManager转移到hive4节点上,观察报错情况,没有变化,报错的仍然是hive1/2,hive3/4仍为正常,证明与负载无关。

4.故障分析阶段(系统层面)

1. 在排查过程中,发现报错的hive01,hive02以及hbase集群的四个节点系统语

言皆为中文,但未报错的hive03则hive04则都为英文:

2. 使用rpm -qa命令查看hive集群四个节点所安装的rpm包信息,对比之后发

现hive03与hive04所安装的RPM包完全一致,而hive01与hive02除了hive03上有的rpm之外,还有很多其他的RPM包,在安装平台时系统环境其实并不一致,推测是由系统环境不一致引起的异常,在安装集群之前,节点系统的环境相对已不纯净,可能是由于某些第三方依赖包引起了网络不稳定。计划依次采取如下方案继续测试:

更改语言环境更换网卡及光纤通信线逐台节点下线重装系统

3. 在更换了hive01与hive02的系统语言环境为英文,并重启了节点之后,”Broken Pipe”异常未再出现。Hbase集群采取同样的操作后,该异常也未再出现。

5.总结

1. 该异常的处理办法是将系统语言改为英文;

2. CDH无系统语言必须为英文的要求,推测可能的原因一方面是否安装的中文字符集有问题或者该字符集与CentOS6.8兼容性并不好;另一方面,从各个节点上安装的依赖包来看,还安装了很多第三方的依赖包,是否存在部分依赖包在中文环境下会导致网络不稳定的情况。

标签: #java断开的管道