Hadoop 2.6.5 FileSystem和Configuration两个对象的探究

版权声明:本文为yunshuxueyuan原创文章,如需转载,请标明出处。【http://www.cnblogs.com/sxt-zkys/】
QQ技术交流群:299142667

 (结论)

通过尚学堂旗下云数学院大数据周老师的讲解可以得到以下结论:用相同的地址获取的FileSystem对象是同一个; 第一次获取对象后会有类似于缓存的机制, 即使改变了configuration参数, 只要地址没有发生变化, 获取的FileSystem 对象不会改变.

[从bug开始]

在测试上传数据到HDFS集群时, 想更改blocksize的大小来测试小文件分块的情况, 使用了如下代码(为了便于阅读, 删去了JUNIT的注解):

Configuration conf = null; FileSystem fs = null; 

 //初始化fs对象 

 conf = new Configuration(true); 

 fs = FileSystem.get(conf);

 //更改blocksize大小 

 conf.set("dfs.blocksize", "1048576"); 

 fs = FileSystem.get(conf); 

 //上传文件

 Path srcPath = new Path("d:\\testup.txt");

 Path dstPath = new Path("/user/root/test03.txt");

 fs.copyFromLocalFile(srcPath, dstPath);

从结果来看, 生成的文件大小并没有改变:

那我们重新定义一个FileSystem来尝试一下:

于是接着上段代码, 有了如下代码:

//初始化fs2对象 

 Configuration conf2 = new Configuration(true);

 conf2.set("dfs.blocksize", "1048576"); 

 FileSystem fs2 = FileSystem.get(conf2); 

 //上传文件 

 Path dstPath2 = new Path("/user/root/test04.txt");

 fs2.copyFromLocalFile(srcPath, dstPath2);

然而结果并不乐观:

此时其他的小伙伴@2元店主 已经完成了测试, 上传文件成功, 并且设置分块大小也没有问题, 他的代码如下:

//初始化fs对象 

 Path srcPath = new Path("d:\\testup.txt"); 

 Path dstPath = new Path("/user/root/test07.txt"); 

Configuration confnew = new Configuration(true);

 confnew.set("dfs.blocksize", "1048576"); 

 FileSystem fsnew = FileSystem.get(confnew); 

 //上传文件 

 fsnew.copyFromLocalFile(srcPath, dstPath);

对比可以发现, 其中的核心代码并没有什么差异, 那么是什么问题引起的blocksize改变不成功呢?

经过尚学堂同班同学的大力协助, 我们确定了差异点, 在我的测试代码中, 先从配置(conf)生成过了一次FileSystem对象, 更改的blocksize后再次生成FileSystem对象. 可能是这个过程出现了问题.

如果是这个问题, 那么我的第二次测试的代码也失效根本说不过去, 因为我是全新的对象, 与之前对象并无关联.

到了这里, 我们对bug的产生有了一些思路.

[进一步测试]

为了明确具体的问题所在, 有了如下代码:

因为下面的代码长得我都不想仔细读, 所以在这里说一下大概思路:

测试代码两两一组, 每组获取FileSystem对象用的地址是相同的;

第一组读取本地配置文件, 先生成FileSystem对象后更改blocksize配置, 再次生成FileSystem对象

第二组不读取本地配置文件, 地址是node01, 先更改blocksize为1M, 生成FileSystem对象, 改变blocksize为128M, 再次生成FileSystem对象

第三组不读取本地配置文件, 地址是192.168的具体地址, 先更改blocksize为128M, 生成FileSystem对象, 改变blocksize为1M, 再次生成FileSystem对象

最后, 输出所有的FileSystem对象toString方法

//第一组 

 Configuration confa = new Configuration(true); 

FileSystem fsa = FileSystem.get(confa);

confa.set("dfs.blocksize", "1048576"); 

fsa = FileSystem.get(confa); 

System.out.println(fsa.getDefaultBlockSize()); 

Configuration confb = new Configuration(true); 

confb.set("dfs.blocksize", "1048576"); 

FileSystem fsb = FileSystem.get(confb); 

 System.out.println(fsb.getDefaultBlockSize());

//第二组

 Configuration confc = new Configuration(false); 

confc.set("fs.defaultFS", "hdfs://node01:8020"); 

 confc.set("dfs.blocksize", "1048576");

 FileSystem fsc = FileSystem.get(confc); 

 System.out.println(fsc.getDefaultBlockSize());

 Configuration confd = new Configuration(false);

 confd.set("fs.defaultFS", "hdfs://node01:8020"); 

 confd.set("dfs.blocksize", "134217728"); 

FileSystem fsd = FileSystem.get(confd);

 System.out.println(fsd.getDefaultBlockSize());

//第三组 

 Configuration confe = new Configuration(false); 

confe.set("fs.defaultFS", "hdfs://192.168.109.51:8020"); 

 confe.set("dfs.blocksize", "134217728"); 

FileSystem fse = FileSystem.get(confe); 

 System.out.println(fse.getDefaultBlockSize()); 

 Configuration conff = new Configuration(false);

 conff.set("fs.defaultFS", "hdfs://192.168.109.51:8020");

 conff.set("dfs.blocksize", "1048576");

 FileSystem fsf = FileSystem.get(conff);

 System.out.println(fsf.getDefaultBlockSize());

//输出

System.out.println(fsa); 

 System.out.println(fsb); 

 System.out.println(fsc); 

 System.out.println(fsd); 

 System.out.println(fse); 

 System.out.println(fsf);

这次测试获得了预期的结果:

134217728 

134217728 

1048576

1048576

134217728 

134217728 

DFS[DFSClient[clientName=DFSClient_NONMAPREDUCE_1193042798_1, ugi=root (auth:SIMPLE)]] DFS[DFSClient[clientName=DFSClient_NONMAPREDUCE_1193042798_1, ugi=root (auth:SIMPLE)]] DFS[DFSClient[clientName=DFSClient_NONMAPREDUCE_-1041604824_1, ugi=root (auth:SIMPLE)]] DFS[DFSClient[clientName=DFSClient_NONMAPREDUCE_-1041604824_1, ugi=root (auth:SIMPLE)]] DFS[DFSClient[clientName=DFSClient_NONMAPREDUCE_-1719045568_1, ugi=root (auth:SIMPLE)]] DFS[DFSClient[clientName=DFSClient_NONMAPREDUCE_-1719045568_1, ugi=root (auth:SIMPLE)]]

从FileSystem对象的id可以看出, 相同地址获取的对象确实是同一对象, 至此, bug的产生已经可以解释的清楚了

[解决bug后的思考]

从最后的测试的结果可以看出, 源码的实现中有缓存处理, 当已经连接过一次之后, 再次获取FileSystem对象时并不会读取configuration中的参数, 只是根据地址与对象, 从类似于kv对的关系返回真实的FileSystem对象.

在debug模式运行代码会发现, 第一次根据配置生成FileSystem对象时有大约10s的延时, 这应该是服务器通讯造成的, 因为服务器通讯的时间成本太高, 所以才会采取这种缓存的方式返回对象.

一般使用中并不会对配置参数做调整, 因此这种实现方式不能说有问题, 但是如果需要临时更改配置参数时, 则需对这个问题小心一些.

最后, 感谢 尚学堂周老师,在这次解决bug时提供的帮助与思路.

如需下载代码和hadoop安装文件下载:

http://www.bjsxt.com/2015/down_0526/41.html

版权声明:本文为yunshuxueyuan原创文章,如需转载,请标明出处。【http://www.cnblogs.com/sxt-zkys/】
QQ技术交流群:299142667

Hadoop 2.6.5 FileSystem和Configuration两个对象的探究的更多相关文章

  1. Hadoop权威指南:通过FileSystem API读取数据

    Hadoop权威指南:通过FileSystem API读取数据 [TOC] 在Hadoop中,FileSystem是一个通用的文件系统API 获取FileSystem实例的几个静态方法 public ...

  2. Hadoop之HDFS文件操作常有两种方式(转载)

    摘要:Hadoop之HDFS文件操作常有两种方式,命令行方式和JavaAPI方式.本文介绍如何利用这两种方式对HDFS文件进行操作. 关键词:HDFS文件    命令行     Java API HD ...

  3. 全网最详细的Hadoop HA集群启动后,两个namenode都是active的解决办法(图文详解)

    不多说,直接上干货! 这个问题,跟 全网最详细的Hadoop HA集群启动后,两个namenode都是standby的解决办法(图文详解) 是大同小异. 欢迎大家,加入我的微信公众号:大数据躺过的坑  ...

  4. Hadoop 3.1.2报错:xception in thread "main" org.apache.hadoop.fs.UnsupportedFileSystemException: No FileSystem for scheme "hdfs"

    报错内容如下: Exception in thread "main" org.apache.hadoop.fs.UnsupportedFileSystemException: No ...

  5. .net两个对象比较,抛出不一样字段的结果

    现在应该经常用到记录操作日志,修改和新增必定涉及到两个实体的属性值的变动. 利用反射,将变动记录下来. 切记,类中的属性字段上面需要打上Description标签: 例如: /// <summa ...

  6. java比较两个对象是否相等的方法

    java比较两个对象是否相等直接使用equals方法进行判断肯定是不会相同的. 例如: Person  person1  =new Person("张三"); Person  pe ...

  7. 判断java中两个对象是否相等

    java中的基本数据类型判断是否相等,直接使用"=="就行了,相等返回true,否则,返回false. 但是java中的引用类型的对象比较变态,假设有两个引用对象obj1,obj2 ...

  8. js中两个对象的比较

    代码取自于underscore.js 1.8.3的isEqual函数. 做了一些小小的修改,主要是Function的比较修改. 自己也加了一些代码解读. <!DOCTYPE html> & ...

  9. 如果两个对象具有相同的哈希码,但是不相等的,它们可以在HashMap中同时存在吗?

    如果两个对象具有相同的哈希码,但是不相等的,它们可以在HashMap中同时存在吗? ----答案是 可以 原因: 在hashmap中,由于key是不可以重复的,他在判断key是不是重复的时候就判断了h ...

随机推荐

  1. 《物联网框架ServerSuperIO教程》-19.设备驱动和OPC Client支持mysql、oracle、sqlite、sqlserver的持久化。v3.6.4版本发布

    19.设备驱动和OPC Client支持mysql.oracle.sqlite.sqlserver的持久化 19.1     概述 ServerSuperIO支持设备驱动和OPC Client采集的数 ...

  2. boost.property_tree读取中文乱码问题正确的解决方式

    开发项目的时候在使用boost,在宽字符下遇到中文乱码问题 上网上看大家都是先转成utf8在进行解析的,例如: http://blog.csdn.net/hu_jiangan/article/deta ...

  3. BOM(1)

    BOM 浏览器对象模型(Browser Object Model),使浏览器对象模型 (BOM) 使 JavaScript 有能力与浏览器"对话". 浏览器对象模型(Browser ...

  4. Realm的简单使用

    Realm个人理解: 它主要是一套移动端数据库框架,将对数据库表的操作转换为对对象的操作,如果是学过Java ORM框架的同学使用Realm起来应该上手比较快一点.而且据我所知Realm不仅支持Obj ...

  5. spring boot 入门操作(二)

    spring boot入门操作 使用FastJson解析json数据 pom dependencies里添加fastjson依赖 <dependency> <groupId>c ...

  6. SQL之trigger(触发器)

    先来看一小段程序 有如下三张表: 帐户(编号,姓名,余额,建立日期,储蓄所编号) 储蓄所(编号,名称,地址,人数,所属城市) 借贷(帐户,借贷类型,金额,日期) create trigger tri_ ...

  7. POJ 2388

    还是水题,简单的排序.大半夜的,没脑子想太复杂的代码了,就随手找了段以前写的插入排序将就着用了. 题目的意思就是取一个数列的中位数,很简单,排序后取a[n/2]即可. 代码如下: #ifndef _2 ...

  8. 团体队列UVA540 Team Queue(队列简单用法)

    题目背景 队列和优先级队列是大多数计算机科学家都知道的数据结构.但是团队队列却不被人熟知,尽管在生活中经常出现.比如,午餐时间的食堂门口的队列就是一个团队队列.在一个团队队列中,每个元素属于一个团队. ...

  9. 架构漫谈系列(2) 封装(Encapsulation)

    这是这个系列的第二篇.在第二篇里,我决定讲一讲封装. 程序的不同部分应该用封装去互相隔离,模块之间应该不应该产生很随意的关联. 可能有的人觉得不解,又或觉得是有道理的废话,不急,先一步一步来. 我们先 ...

  10. Akka(10): 分布式运算:集群-Cluster

    Akka-Cluster可以在一部物理机或一组网络连接的服务器上搭建部署.用Akka开发同一版本的分布式程序可以在任何硬件环境中运行,这样我们就可以确定以Akka分布式程序作为标准的编程方式了. 在上 ...