Hadoop 2.6.5 FileSystem和Configuration两个对象的探究
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两个对象的探究的更多相关文章
- Hadoop权威指南:通过FileSystem API读取数据
Hadoop权威指南:通过FileSystem API读取数据 [TOC] 在Hadoop中,FileSystem是一个通用的文件系统API 获取FileSystem实例的几个静态方法 public ...
- Hadoop之HDFS文件操作常有两种方式(转载)
摘要:Hadoop之HDFS文件操作常有两种方式,命令行方式和JavaAPI方式.本文介绍如何利用这两种方式对HDFS文件进行操作. 关键词:HDFS文件 命令行 Java API HD ...
- 全网最详细的Hadoop HA集群启动后,两个namenode都是active的解决办法(图文详解)
不多说,直接上干货! 这个问题,跟 全网最详细的Hadoop HA集群启动后,两个namenode都是standby的解决办法(图文详解) 是大同小异. 欢迎大家,加入我的微信公众号:大数据躺过的坑 ...
- 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 ...
- .net两个对象比较,抛出不一样字段的结果
现在应该经常用到记录操作日志,修改和新增必定涉及到两个实体的属性值的变动. 利用反射,将变动记录下来. 切记,类中的属性字段上面需要打上Description标签: 例如: /// <summa ...
- java比较两个对象是否相等的方法
java比较两个对象是否相等直接使用equals方法进行判断肯定是不会相同的. 例如: Person person1 =new Person("张三"); Person pe ...
- 判断java中两个对象是否相等
java中的基本数据类型判断是否相等,直接使用"=="就行了,相等返回true,否则,返回false. 但是java中的引用类型的对象比较变态,假设有两个引用对象obj1,obj2 ...
- js中两个对象的比较
代码取自于underscore.js 1.8.3的isEqual函数. 做了一些小小的修改,主要是Function的比较修改. 自己也加了一些代码解读. <!DOCTYPE html> & ...
- 如果两个对象具有相同的哈希码,但是不相等的,它们可以在HashMap中同时存在吗?
如果两个对象具有相同的哈希码,但是不相等的,它们可以在HashMap中同时存在吗? ----答案是 可以 原因: 在hashmap中,由于key是不可以重复的,他在判断key是不是重复的时候就判断了h ...
随机推荐
- 【MyBatis源码分析】insert方法、update方法、delete方法处理流程(下篇)
Configuration的newStatementHandler分析 SimpleExecutor的doUpdate方法上文有分析过: public int doUpdate(MappedState ...
- 抓包工具 - HttpWatch
HttpWatch是功能强大的网页数据分析工具,集成在IE工具栏,主要功能有网页摘要.cookies管理.缓存管理.消息头发送/接收,字符查询.POST数据.目录管理功能和报告输出.HttpWatch ...
- 如何同时完成多个ajax之后再执行某个方法 ? 使用$.when().done();
jQuery中的$.when()方法比较复杂,这里不作全面讲解,只写一个同时完成多个ajax请求后执行操作的方法. 有时候我们需要等待多个ajax执行完以后,再执行某个操作. 写法如下: $.when ...
- cpp(第八章)
1. #include <iostream> inline int add(int &n) { n= n+; ; } int main() { using namespace st ...
- Dojo初探之4:dojo的event(鼠标/键盘)事件绑定操作(基于dojo1.11.2版本)
前言: 上一章详解了dojo的dom/query操作,本章基于dom/query基础上进行事件绑定操作 dojo的事件 dojo的事件绑定操作分为鼠标和键盘两种进行详解 1.鼠标事件 我们沿用上一章中 ...
- selenium+python元素操作
1.判断元素的属性if i.get_attribute('type') == 'checkbox' 2.获取当前窗口的坐标 driver.get_window_position 获取当前窗口的长宽 d ...
- APUE-文件和目录(六)函数ftw和nftw
名字 ftw,nftw - 文件树遍历 概要 #include <ftw.h> int nftw(const char *dirpath, int (*fn) (const char *f ...
- 关于getHTML()方法和getHtmlAjax()方法 GetHttpLength, 清除HTML标签
public string getHtml(string Url, string type = "UTF-8") { try { System.Net.WebRequest wRe ...
- CentOS下安装php的mbstring扩展
php的mbstring扩展如果没有安装会导致一些问题: 例1:登陆phpMyAdmin的时候会提示没字符串编码和字符串处理库 php_mbstring,有些程序中会用到mb_substr函数没有ph ...
- Mysql按时间段分组查询
Mysql按时间段分组查询来统计会员的个数,mysql个数 Mysql按时间段分组查询来统计会员的个数,mysql个数 1.使用case when方法(不建议使用)- 代码如下 复制代码SELECT ...