一、问题起源及详细异常

近日写程序定时任务调Hadoop MR程序,然后生成报表,发送邮件,当时起了两个任务A和B,调MR程序之前,会操作hdfs(读写都有),任务A每天一点跑,任务B每十分钟跑一次,B任务不会调用MR程序,纯粹采集数据。结果第一天就发现任务A没有发送邮件,于是乎查日志,异常信息如下

java.io.IOException: Failed on local exception: java.io.InterruptedIOException: Interrupted while waiting for IO on channel java.nio.channels.SocketChannel[connected local=/10.1.23.249:52305 remote=/10.1.23.249:9000]. 60000 millis timeout left.; Host Details : local host is: "hadoop-alone-test/10.1.23.249"; destination host is: "hadoop-alone-test":9000;
at org.apache.hadoop.net.NetUtils.wrapException(NetUtils.java:776)
at org.apache.hadoop.ipc.Client.call(Client.java:1479)
at org.apache.hadoop.ipc.Client.call(Client.java:1412)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:229)
at com.sun.proxy.$Proxy109.getListing(Unknown Source)
........

当时有点懵,不知道为什么出现这种IO被中断。于是乎,我在job控制台再调一下,并没有出现错误。本来想看看源码,但是领导安排了个比较紧急的任务。忙了几天,期间没有仔细去管,我只是注意了下每天的邮件,发现还是有的时候会成功的。忙完了任务,赶紧来排查,再看日志,发现报的错不止这一种,下面列出其他错误

java.io.IOException: Failed on local exception: java.io.IOException; Host Details : local host is: "hadoop-alone-test/10.1.23.249"; destination host is: "hadoop-alone-test":9000;
at org.apache.hadoop.net.NetUtils.wrapException(NetUtils.java:776)
at org.apache.hadoop.ipc.Client.call(Client.java:1479)
at org.apache.hadoop.ipc.Client.call(Client.java:1412)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:229)
at com.sun.proxy.$Proxy109.getFileInfo(Unknown Source)
...........
java.io.IOException: Filesystem closed
at org.apache.hadoop.hdfs.DFSClient.checkOpen(DFSClient.java:808)
at org.apache.hadoop.hdfs.DFSClient.listPaths(DFSClient.java:2083)
at org.apache.hadoop.hdfs.DistributedFileSystem$DirListingIterator.<init>(DistributedFileSystem.java:944)
at org.apache.hadoop.hdfs.DistributedFileSystem$DirListingIterator.<init>(DistributedFileSystem.java:927)
at org.apache.hadoop.hdfs.DistributedFileSystem$19.doCall(DistributedFileSystem.java:872)
at org.apache.hadoop.hdfs.DistributedFileSystem$19.doCall(DistributedFileSystem.java:868)
at org.apache.hadoop.fs.FileSystemLinkResolver.resolve(FileSystemLinkResolver.java:81)
................
java.io.IOException: The client is stopped
at org.apache.hadoop.ipc.Client.getConnection(Client.java:1507)
at org.apache.hadoop.ipc.Client.call(Client.java:1451)
at org.apache.hadoop.ipc.Client.call(Client.java:1412)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:229)
at com.sun.proxy.$Proxy109.getFileInfo(Unknown Source)
at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.getFileInfo(ClientNamenodeProtocolTranslatorPB.java:771)
at sun.reflect.GeneratedMethodAccessor69.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)

就是上述这四个错误,都是和io通信有关,然后都出现在操作Hadoop的FileSystem那段代码,且任务A和B都不等量的出现过,而且出现在凌晨一点,两个线程同时操作的时候,所以问题很明确,出在并发上面,联系到上面的FileSystem被关闭,我代码确实是调用了close方法

于是查看了一下源码,创建FileSystem的时候有如下代码

String disableCacheName = String.format("fs.%s.impl.disable.cache", scheme);
return conf.getBoolean(disableCacheName, false) ? createFileSystem(uri, conf) : CACHE.get(uri, conf);

创建FileSystem的时候读取配置"fs.%s.impl.disable.cache",默认为false,所以第二次走了缓存, FileSystem的URI相同的话,一定只创建一个FileSystem

涉及到多线程访问,而线程B已经调用了filesystem.close()方法,这个时候线程A还在操作filesystem,所以报错上面种种异常

二、解决办法

1、代码同步(这里就不贴代码,用synchronized、lock这些都行)

2、禁用FileSystem缓存

代码里

Configuration conf = new Configuration();
conf.set("fs.hdfs.impl.disable.cache", "true");

core-site.xml文件里面配置(二者选其一)

<property>
<name>fs.hdfs.impl.disable.cache</name>
<value>true</value>
</property>

关于操作HDFS的一个问题的更多相关文章

  1. java操作hdfs实例

    环境:window7+eclipse+vmware虚拟机+搭建好的hadoop环境(master.slave01.slave02) 内容:主要是在windows环境下,利用eclipse如何来操作hd ...

  2. Hadoop操作hdfs的命令【转载】

    本文系转载,原文地址被黑了,故无法贴出原始链接. Hadoop操作HDFS命令如下所示: hadoop fs 查看Hadoop HDFS支持的所有命令 hadoop fs –ls 列出目录及文件信息 ...

  3. 使用javaAPI操作hdfs

    欢迎到https://github.com/huabingood/everyDayLanguagePractise查看源码. 一.构建环境 在hadoop的安装包中的share目录中有hadoop所有 ...

  4. 使用Java API操作HDFS文件系统

    使用Junit封装HFDS import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.*; import org ...

  5. 使用Eclipse来操作HDFS的文件

    一.常用类 1.Configuration Hadoop配置文件的管理类,该类的对象封装了客户端或者服务器的配置(配置集群时,所有的xml文件根节点都是configuration) 创建一个Confi ...

  6. Hadoop Java API操作HDFS文件系统(Mac)

    1.下载Hadoop的压缩包 tar.gz   https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/stable/ 2.关联jar包 在 ...

  7. Hadoop基础-通过IO流操作HDFS

    Hadoop基础-通过IO流操作HDFS 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.上传文件 /* @author :yinzhengjie Blog:http://www ...

  8. 使用Java Api 操作HDFS

    如题 我就是一个标题党  就是使用JavaApi操作HDFS,使用的是MAVEN,操作的环境是Linux 首先要配置好Maven环境,我使用的是已经有的仓库,如果你下载的jar包 速度慢,可以改变Ma ...

  9. Java代码操作HDFS测试类

    1.Java代码操作HDFS需要用到Jar包和Java类 Jar包: hadoop-common-2.6.0.jar和hadoop-hdfs-2.6.0.jar Java类: java.net.URL ...

随机推荐

  1. Shell中数组的使用

    数组是一个很有用的数据结构,经常使用的功能有初始化,遍历,查找,获取数组长度等操作 一.初始化 小括号中使用空格分开的数据结构就是一个数组,也可使用下标添加元素 arr=(1 'nice' '2day ...

  2. Neutron vxlan network--L2 Population

    L2 Population 是用来提高 VXLAN 网络 Scalability 的.   通常我们说某个系统的 Scalability 好,其意思是: 当系统的规模变大时,仍然能够高效地工作. L2 ...

  3. PyCharm选中文件夹新建时Directory与Python package的区别

    pycharm创建普通的directory和package时都是在硬盘上建立一个文件夹.但是建package时会在这个文件夹中自动地生成一个空的__init__.py文件.python的一个包是一个带 ...

  4. Python之路【第十七篇】:Django【进阶篇 】(转自银角大王博客)

    Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层执行 ...

  5. linux上面sqlserver数据库的操作

    sqlserver2017可以安装到linux也不是什么新鲜事, centos安装好sqlserver后有一写操作 systemctl status mssql-server:查看sqlserver的 ...

  6. asp.net core 2.2 中的过滤器/筛选器(上)

    ASP.NET Core中的过滤器/筛选器 通过使用 ASP.NET Core MVC 中的筛选器,可在请求处理管道中的特定阶段之前或之后运行代码. 注意:本主题不适用于 Razor 页面. ASP. ...

  7. ArrayList如何扩容?

    1.调用ArrayList的参构造方法,此时集合内部是一个空数组 transient Object[] elementData; private static final Object[] DEFAU ...

  8. CentOS_7下安装MySQL

    卸载旧版本MySQl: 下载MySQ: MySQl官网:https://dev.mysql.com/downloads/mysql/ 版本自选,操作系统选Linux-Generic,64位系统或者32 ...

  9. sprigboot recontroller 是responsebody与controller结合 这样 就使每个方法默认返回json

    sprigboot   recontroller 是responsebody与controller结合 这样 就使每个方法默认返回json

  10. react 生命周期函数介绍

    constructor():构造函数 执行:组件加载钱最先调用一次,仅调用一次. 作用:定义状态机变量. 注意:第一个语句必须为super(), 否则会报错:'this' is not allowed ...