从Java写入HDFS,得到“只能复制到0个节点,而不是最小复制”更新

2022-09-01 23:31:45

我已经下载并启动了Cloudera的Hadoop Demo VM for CDH4(运行Hadoop 2.0.0)。我正在尝试编写一个 Java 程序,该程序将从我的 Windows 7 计算机(运行 VM 的同一台计算机/操作系统)运行。我有一个示例程序,例如:

public static void main(String[] args) {
    try{
        Configuration conf = new Configuration();
        conf.addResource("config.xml");
        FileSystem fs = FileSystem.get(conf);
        FSDataOutputStream fdos=fs.create(new Path("/testing/file01.txt"), true);
        fdos.writeBytes("Test text for the txt file");
        fdos.flush();
        fdos.close();
        fs.close();
    }catch(Exception e){
        e.printStackTrace();
    }

}

我的config.xml文件只有属性定义:fs.default.name=hdfs://CDH4_IP:8020。

当我运行它时,我得到以下异常:

org.apache.hadoop.ipc.RemoteException(java.io.IOException): File /testing/file01.txt could only be replicated to 0 nodes instead of minReplication (=1).  There are 1 datanode(s) running and 1 node(s) are excluded in this operation.
    at org.apache.hadoop.hdfs.server.blockmanagement.BlockManager.chooseTarget(BlockManager.java:1322)
    at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getAdditionalBlock(FSNamesystem.java:2170)
    at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.addBlock(NameNodeRpcServer.java:471)
    at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.addBlock(ClientNamenodeProtocolServerSideTranslatorPB.java:297)
    at org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$ClientNamenodeProtocol$2.callBlockingMethod(ClientNamenodeProtocolProtos.java:44080)
    at org.apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine.java:453)
    at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:898)
    at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:1693)
    at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:1689)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:396)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1332)
    at org.apache.hadoop.ipc.Server$Handler.run(Server.java:1687)
    at org.apache.hadoop.ipc.Client.call(Client.java:1160)
    at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:202)
    at $Proxy9.addBlock(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:164)
    at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:83)
    at $Proxy9.addBlock(Unknown Source)
    at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.addBlock(ClientNamenodeProtocolTranslatorPB.java:290)
    at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.locateFollowingBlock(DFSOutputStream.java:1150)
    at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.nextBlockOutputStream(DFSOutputStream.java:1003)
    at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.run(DFSOutputStream.java:463)

我环顾了一下互联网,似乎当磁盘空间不足时会发生这种情况,但是当我运行“hdfs dfsadmin -report”时,情况并非如此,我得到以下结果:

Configured Capacity: 25197727744 (23.47 GB)
Present Capacity: 21771988992 (20.28 GB)
DFS Remaining: 21770715136 (20.28 GB)
DFS Used: 1273856 (1.21 MB)
DFS Used%: 0.01%
Under replicated blocks: 0
Blocks with corrupt replicas: 0
Missing blocks: 0

-------------------------------------------------
Datanodes available: 1 (1 total, 0 dead)

Live datanodes:
Name: 127.0.0.1:50010 (localhost.localdomain)
Hostname: localhost.localdomain
Decommission Status : Normal
Configured Capacity: 25197727744 (23.47 GB)
DFS Used: 1273856 (1.21 MB)
Non DFS Used: 3425738752 (3.19 GB)
DFS Remaining: 21770715136 (20.28 GB)
DFS Used%: 0.01%
DFS Remaining%: 86.4%
Last contact: Fri Jan 11 17:30:56 EST 201323 EST 2013

我还可以在VM中运行此代码。我不确定问题是什么或如何解决它。这是我第一次使用hadoop,所以我可能错过了一些基本的东西。有什么想法吗?

更新

我在日志中看到的唯一一件事是一个异常,类似于 get on the client 上的异常:

java.io.IOException: File /testing/file01.txt could only be replicated to 0 nodes instead of minReplication (=1).  There are 1 datanode(s) running and 1 node(s) are excluded in this operation.
    at org.apache.hadoop.hdfs.server.blockmanagement.BlockManager.chooseTarget(BlockManager.java:1322)
    at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getAdditionalBlock(FSNamesystem.java:2170)
    at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.addBlock(NameNodeRpcServer.java:471)
    at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.addBlock(ClientNamenodeProtocolServerSideTranslatorPB.java:297)
    at org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$ClientNamenodeProtocol$2.callBlockingMethod(ClientNamenodeProtocolProtos.java:44080)
    at org.apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine.java:453)
    at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:898)
    at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:1693)
    at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:1689)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:396)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1332)
    at org.apache.hadoop.ipc.Server$Handler.run(Server.java:1687)

我尝试更改数据目录(/var/lib/hadoop-hdfs/cache/hdfs/dfs/data)的权限,但这并没有解决它(我甚至给每个人提供完全访问权限)。

我注意到,当我通过HUE Web应用程序浏览HDFS时,我看到文件夹结构已创建,并且该文件确实存在,但它是空的。我尝试使用

FSDataOutputStream fdos=fs.create(new Path("testing/file04.txt"), true); 

而不是

FSDataOutputStream fdos=fs.create(new Path("/testing/file04.txt"), true);

这使得文件路径变为“/user/dharris/testing/file04.txt”('dharris'是我的Windows用户)。但这给了我同样的错误。


答案 1

我遇到了同样的问题。
在我的情况下,问题的关键是遵循错误消息。
此操作中有 1 个数据节点正在运行,并且排除了 1 个节点。

这意味着您的 hdfs 客户端无法连接到具有 50010 端口的数据节点。当您连接到hdfs namenode时,您可以获得数据节点的状态。但是,您的 hdfs 客户端将无法连接到您的数据节点。

(在 hdfs 中,namenode 管理文件目录和数据节点。如果 hdfs-client 连接到 namnenode,它将找到包含该数据的数据节点的目标文件路径和地址。然后hdfs-client将与datanode通信。(您可以使用 netstat 检查这些数据节点 uri,因为 hdfs-client 将尝试使用 namenode 通知的地址与 datanode 进行通信)

通过以下方式解决了这个问题:

  1. 在防火墙中打开 50010(dfs.datanode.address) 端口。
  2. 添加属性"dfs.client.use.datanode.hostname", "true"
  3. 将主机名添加到我的客户端 PC 中的主机文件。

我很抱歉我的英语水平很差。


答案 2

转到 linux VM 并检查主机名和 iP 地址(使用 ifconfig cmd)。然后在 linux vm 中编辑 /etc/host 文件

IPADDRESS (SPALCE) 主机名

示例 : 192.168.110.27 clouderavm

并更改所有hadoop配置文件,例如

核心站点.xml

hdfs-site.xml

地图网站.xml

纱线现场.xml

localhost 或 localhost.localdomain 或 0.0.0.0 更改为您的主机名

然后重新启动云埃拉管理器。

在窗口计算机中编辑 C:\Windows\System32\Drivers\etc\hosts

在末尾添加一行

您的虚拟机计算机 IP 和主机名(与您在虚拟机中的 /etc/host 文件上执行的操作相同)

VMIPADRESS VMHOSTNAME

例:

192.168.110.27 clouderavm

然后现在检查,它应该工作,详细的配置检查下面的视频从你的管

https://www.youtube.com/watch?v=fSGpYHjGIRY


推荐