23

我已经为 CDH4 下载并启动了 Cloudera 的 Hadoop Demo VM(运行 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,所以我可能缺少一些基本的东西。有任何想法吗?

更新

我在日志中看到的唯一一件事是一个类似于客户端上的异常:

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 用户)。但这给了我同样的错误。

4

11 回答 11

18

我遇到了同样的问题。
就我而言,问题的关键在于错误消息。
有 1 个数据节点正在运行,并且在此操作中排除了 1 个节点。

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

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

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

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

我为我糟糕的英语水平感到抱歉。

于 2016-04-04T02:36:24.710 回答
3

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

IPADDRESS (SPALCE) 主机名

示例:192.168.110.27 clouderavm

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

核心站点.xml

hdfs-site.xml

mapred-site.xml

纱线站点.xml

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

然后重启cloudera manager。

在 windows 机器中编辑C:\Windows\System32\Drivers\etc\hosts

在末尾添加一行

您的 vm 机器 ip 和主机名(与您在 vm 中的 /etc/host 文件上所做的相同)

VMIPADDRESS VM主机名

例子 :

192.168.110.27 clouderavm

然后现在检查,它应该可以工作,请按照您的视频进行详细配置检查

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

于 2015-12-02T07:34:03.493 回答
2

添加给定的属性hdfs-site.xml

<property>
   <name>dfs.replication</name>
   <value>1</value>
 </property>

并将此文件也添加到您的程序中

conf.addResource("hdfs-site.xml");

停止 hadoop

stop-all.sh

然后开始

start-all.sh
于 2015-07-29T06:28:55.127 回答
1

我遇到了类似的问题,有两条信息可以帮助你。

  1. 我意识到的第一件事是我使用 ssh 隧道访问名称节点,当客户端代码尝试访问数据节点时,由于隧道以某种方式破坏了通信,它找不到数据节点。然后我在与 hadoop 名称节点相同的盒子上运行客户端,它解决了这个问题。简而言之,非标准的网络配置混淆了hadoop寻找数据节点。

  2. 我使用ssh隧道的原因是我无法远程访问name node,我认为这是由于管理员的端口限制,所以我使用ssh隧道绕过限制。但事实证明这是hadoop的错误配置。

在我更改后的 core-site.xml 中

<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>

<value>hdfs://host_name:9000</value>

我不再需要 ssh turnnel,我可以远程访问 hdfs。

于 2015-12-02T00:39:06.690 回答
1

由于我在寻找完全相同的问题时发现了很多类似的问题,所以我想我会分享最终对我有用的方法。我在 Hortonworks 上找到了这个论坛帖子:https ://community.hortonworks.com/questions/16837/cannot-copy-from-local-machine-to-vm-datanode-via.html

答案是真正理解调用 new Configuration() 的含义并根据需要设置正确的参数。就我而言,这正是那篇文章中提到的那个。所以我的工作代码看起来像这样。

try {
    Configuration config = new Configuration();
    config.set("dfs.client.use.datanode.hostname", "true");
    Path pdFile = new Path("stgicp-" + pd);
    FileSystem dFS = FileSystem.get(new URI("hdfs://" + HadoopProperties.HIVE_HOST + ":" + HadoopProperties.HDFS_DEFAULT_PORT), config, 
            HadoopProperties.HIVE_DEFAULT_USER);
    if (dFS.exists(pdFile)) {
        dFS.delete(pdFile, false);
    } 
    FSDataOutputStream outStream = dFS.create(pdFile);
    for (String sjWLR : processWLR.get(pd)) {
        outStream.writeBytes(sjWLR);
    }     
    outStream.flush();
    outStream.close();

    dFS.delete(pdFile, false);
    dFS.close();
} catch (IOException | URISyntaxException | InterruptedException e) {
    log.error("WLR file processing error: " + e.getMessage());
}
于 2016-11-03T12:58:20.363 回答
0

您可以尝试手动删除数据(dfs/data)文件夹并格式化namenode。然后就可以启动hadoop了。

于 2013-05-02T08:35:51.243 回答
0

在 hadoop 配置中,默认复制设置为 3。检查一次并根据您的要求进行更改

于 2013-03-14T09:52:34.387 回答
0

从错误消息复制因子似乎很好 ie1。似乎 datanode 运行正常或存在权限问题。检查权限并检查用户的datanode状态,您正在尝试运行hadoop。

于 2013-07-30T10:11:16.280 回答
0

我有一个类似的问题,就我而言,我只是清空了以下文件夹${hadoop.tmp.dir}/nm-local-dir/usercache/{{hdfs_user}}/appcache/

于 2015-01-08T14:20:24.337 回答
0

FS好像有点问题。cross-site.xml 中的参数与它尝试读取的文件不匹配

或者

路径中有一些常见的不匹配(我看到有一个 WINDOWS 参考)。

您可以使用 cygwin 工具设置路径并将其放置在放置数据节点和临时文件位置的位置,这应该足以解决问题 Location : $/bin/cygpath.exe

在我看来, PS复制似乎不是这里的主要问题

于 2015-08-10T05:13:57.537 回答
0

这是我在 HDFS 中创建文件的方法:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

FileSystem hdfs = FileSystem.get(context.getConfiguration());
Path outFile=new Path("/path to store the output file");

String line1=null;

if (!hdfs.exists(outFile)){
            OutputStream out = hdfs.create(outFile);
            BufferedWriter br = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
            br.write("whatever data"+"\n");
            br.close();
            hdfs.close();
        }
else{
            String line2=null;
            BufferedReader br1 = new BufferedReader(new InputStreamReader(hdfs.open(outFile)));
            while((line2=br1.readLine())!=null){
                line1=line1.concat(line2)+"\n";
            }
            br1.close();
            hdfs.delete(outFile, true);
            OutputStream out = hdfs.create(outFile);
            BufferedWriter br2 = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
            br2.write(line1+"new data"+"\n");
            br2.close();
            hdfs.close();
        }
于 2015-10-12T06:45:30.563 回答