设为首页 加入收藏

TOP

Java HDFS API 追加文件写入内容异常问题的解决
2018-11-29 08:13:05 】 浏览:128
Tags:Java HDFS API 追加 文件 写入 内容 异常 问题 解决
版权声明:有问题的请留言 喜欢的请给个赞 --------------------------------不定时会更新,因为学习,所以快乐,因为分享,所以便捷!转载请标注出处,哈哈! https://blog.csdn.net/Appleyk/article/details/80846618



最近在完善一个Java HDFS 的Api功能类,其功能列表如下(主要利用文件系统进行文件或目录的各种操作):






上述功能有:

1、获取当前HDFS系统的状态,如容量多少,使用了多少,剩余多少(getStatus())

2、打开一个文件,并返回打开后的FS数据的输出流,便于向文件里编写内容(open(destPath))

3、上传本地(local或remote)文件至HDFS文件系统(upLoadFile(srcPath,destPath,dealSrc,override))

4、文件或目录的重命名(rename(srcPath,destPath))

5、验证HDFS的回收站功能是否开启(trashEnabled()) ....etc






上述功能有:


1、拿到文件系统的回收站路径(getTrashDirPath())

2、将文件或目录移除(搬家)到回收站(开启Hadoop回收站功能,并设置文件的回收周期和检查点,可参考我的上一篇文章

3、将回收站中指定的文件或目录进行还原(恢复,restoreFromTrash(srcPath,destPath))

4、清空回收站(emptyTrash())

5、打开已存在的文件,并进行文件内容的追加(appendStringToFile(srcPath,content)) ....etc



在进行文件追加内容的demo测试时,报了一段异常,以追加文件1.txt为例







测试demo如下:



	/**
	 * 追加文件,添加内容
	 */
	@Test
	public void appendFile() throws Exception {
		initApi();
		api.appendStringToFile("1.txt", "2018年6月28日17:49:50");
		api.close();
	}
	


运行后,报异常如下:


java.io.IOException: Failed to replace a bad datanode on the existing pipeline due to no more good datanodes being available to try. (Nodes: current=[DatanodeInfoWithStorage[192.168.142.142:9866,DS-739b593f-ef79-4b6f-9e88-99761faf4064,DISK], DatanodeInfoWithStorage[192.168.142.143:9866,DS-be84ef18-1fb3-4859-adee-85eef093ac02,DISK]], original=[DatanodeInfoWithStorage[192.168.142.142:9866,DS-739b593f-ef79-4b6f-9e88-99761faf4064,DISK], DatanodeInfoWithStorage[192.168.142.143:9866,DS-be84ef18-1fb3-4859-adee-85eef093ac02,DISK]]). The current failed datanode replacement policy is DEFAULT, and a client may configure this via 'dfs.client.block.write.replace-datanode-on-failure.policy' in its configuration.
	at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.findNewDatanode(DFSOutputStream.java:929)
	at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.addDatanode2ExistingPipeline(DFSOutputStream.java:984)
	at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.setupPipelineForAppendOrRecovery(DFSOutputStream.java:1131)
	at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.run(DFSOutputStream.java:455)


Failed to replace a bad datanode on the existing pipeline due to no more good datanodes being available to try.

异常意思大概是:由于可用的DataNode不多了,导致当前管道中坏掉的DataNode无法被替换


直接贴出解决方案,在Client端,设置conf的properties如下:



Configuration conf = new Configuration();
	
/**
 * dfs.client.block.write.replace-datanode-on-failure.enable=true
 * 如果在写入管道中存在一个DataNode或者网络故障时,
 * 那么DFSClient将尝试从管道中删除失败的DataNode,
 * 然后继续尝试剩下的DataNodes进行写入。
 * 结果,管道中的DataNodes的数量在减少。
 * enable :启用特性,disable:禁用特性
 * 该特性是在管道中添加新的DataNodes。
 * 当集群规模非常小时,例如3个节点或更少时,集群管理员可能希望将策略在默认配置文件里面设置为NEVER或者禁用该特性。
 * 否则,因为找不到新的DataNode来替换,用户可能会经历异常高的管道写入错误,导致追加文件操作失败
 */
conf.set("dfs.client.block.write.replace-datanode-on-failure.enable", "true");

/**
 * dfs.client.block.write.replace-datanode-on-failure.policy=DEFAULT
 * 这个属性只有在dfs.client.block.write.replace-datanode-on-failure.enable设置true时有效:
 * ALWAYS :当一个存在的DataNode被删除时,总是添加一个新的DataNode
 * NEVER  :永远不添加新的DataNode
 * DEFAULT:副本数是r,DataNode的数时n,只要r >= 3时,或者floor(r/2)大于等于n时
 * r>n时再添加一个新的DataNode,并且这个块是hflushed/appended
 */
conf.set("dfs.client.block.write.replace-datanode-on-failure.policy", "NEVER");


看来集群小了,也是事啊(我本地测试环境,只有两个DataNode,索性直接启动该特性,失败的时候添加新的DataNode)


在运行一次demo,这次无异常抛出







我们下载1.txt到本地,并查看内容如下:








】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇hadoop hdfs dfsadmin 介绍 下一篇hdfs心跳机制

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目