我在安装简单的Hadoop时遇到了一些麻烦。我已经下载了hadoop 2.4.0并安装在一个CentOS Linux节点(虚拟机)上。我已经为apache站点(http://hadoop.apache.org/docs/r2.4.0/hadoop-project-dist/hadoop-common/SingleCluster.html)中描述的具有伪分发的单个节点配置了hadoop。它从日志中没有问题开始,我可以使用命令行中的“hadoop fs”命令读取+写入文件。
我正在尝试使用Java API从远程计算机上的HDFS读取文件。机器可以连接并列出目录内容。它还可以确定文件是否存在,代码为:
Path p=new Path("hdfs://test.server:9000/usr/test/test_file.txt");
FileSystem fs = FileSystem.get(new Configuration());
System.out.println(p.getName() + " exists: " + fs.exists(p));
系统打印“true”表示它存在。但是,当我尝试使用以下内容读取文件时
BufferedReader br = null;
try {
Path p=new Path("hdfs://test.server:9000/usr/test/test_file.txt");
FileSystem fs = FileSystem.get(CONFIG);
System.out.println(p.getName() + " exists: " + fs.exists(p));
br=new BufferedReader(new InputStreamReader(fs.open(p)));
String line = br.readLine();
while (line != null) {
System.out.println(line);
line=br.readLine();
}
}
finally {
if(br != null) br.close();
}
此代码抛出异常:
线程中的异常" main" org.apache.hadoop.hdfs.BlockMissingException:无法获取块:BP-13917963-127.0.0.1-1398476189167:blk_1073741831_1007 file = / usr / test / test_file.txt
谷歌搜索提供了一些可能的提示,但都检查了。数据节点已连接,处于活动状态,并且具有足够的空间。来自hdfs dfsadmin -report的管理员报告显示:
配置容量:52844687360(49.22 GB)
现有容量:48507940864(45.18 GB)
DFS剩余:48507887616(45.18 GB)
使用的DFS:53248(52 KB)
使用DFS%:0.00%
在复制的块下:0
具有损坏副本的块:0
缺少块:0
Datanodes可用:1(总共1个,0个死亡)
实时数据节点:
名称:127.0.0.1:50010(test.server)
主机名:test.server
退役状态:正常
配置容量:52844687360(49.22 GB)
使用的DFS:53248(52 KB)
非DFS使用:4336746496(4.04 GB)
DFS剩余:48507887616(45.18 GB)
使用DFS%:0.00%
DFS剩余%:91.79%
配置的缓存容量:0(0 B)
使用的缓存:0(0 B)
剩余高速缓存:0(0 B)
使用缓存%:100.00%
剩余高速缓存%:0.00%
最后联系人:2014年4月25日星期五22:16:56
客户端jar直接从hadoop安装中复制,因此没有版本不匹配。我可以使用Java类浏览文件系统并读取文件属性。我没有得到异常就无法读取文件内容。如果我尝试使用代码编写文件:
FileSystem fs = null;
BufferedWriter br = null;
System.setProperty("HADOOP_USER_NAME", "root");
try {
fs = FileSystem.get(new Configuraion());
//Path p = new Path(dir, file);
Path p = new Path("hdfs://test.server:9000/usr/test/test.txt");
br = new BufferedWriter(new OutputStreamWriter(fs.create(p,true)));
br.write("Hello World");
}
finally {
if(br != null) br.close();
if(fs != null) fs.close();
}
这会创建文件,但不会写任何字节并抛出异常:
线程中的异常" main" org.apache.hadoop.ipc.RemoteException(java.io.IOException):文件/usr/test/test.txt只能复制到0个节点而不是minReplication(= 1)。在此操作中,有1个数据节点正在运行且1个节点被排除。
谷歌搜索表明可能存在空间问题但是从dfsadmin报告来看,似乎有足够的空间。这是一个简单的vanilla安装,我无法解决这个问题。
环境摘要是:
SERVER:
带有伪分发的Hadoop 2.4.0(http://hadoop.apache.org/docs/r2.4.0/hadoop-project-dist/hadoop-common/SingleCluster.html)
CentOS 6.5虚拟机64位服务器 Java 1.7.0_55
客户端:
Windows 8(虚拟机) Java 1.7.0_51
非常感谢任何帮助。
答案 0 :(得分:2)
Hadoop错误消息令人沮丧。他们常常没有说出他们的意思,也没有与真正的问题无关。我发现当客户端,namenode和datanode无法正常通信时会发生这样的问题。在你的情况下,我会选择以下两个问题之一:
主机名“test.server”非常可疑。检查以下所有内容:
必须删除使用FQDN,主机名,数字IP和localhost的任何不一致。不要在conf文件或客户端代码中混用它们。一致使用FQDN是优选的。一致使用数字IP通常也有效。使用非限定主机名,localhost或127.0.0.1会导致问题。
答案 1 :(得分:1)
上面的答案指向了正确的方向。请允许我添加以下内容:
您可以列出目录内容,因为您的客户端代码可以访问hostname:9000
。你正在做上面的数字2
为了能够读写,您的客户端代码需要访问Datanode(编号3)。 Datanode DFS数据传输的默认端口是50010.阻止客户端与hostname:50010
的通信。可能是防火墙或SSH隧道配置问题
我使用的是Hadoop 2.7.2,所以你可能有不同的端口号设置。
答案 2 :(得分:1)
我们需要确保使用fs.default.name空间设置进行配置,例如
configuration.set("fs.default.name","hdfs://ourHDFSNameNode:50000");
我在下面放了一段示例代码:
Configuration configuration = new Configuration();
configuration.set("fs.default.name","hdfs://ourHDFSNameNode:50000");
FileSystem fs = pt.getFileSystem(configuration);
BufferedReader br = new BufferedReader(new InputStreamReader(fs.open(pt)));
String line = null;
line = br.readLine
while (line != null) {
try {
line = br.readLine
System.out.println(line);
}
}