解决File ~ could only be written to 0 of the 1 minReplication nodes.

本文解决了HDFS上传文件失败的问题,原因在于NameNode返回DataNode的私有IP导致本地无法访问。通过配置Hadoop客户端并映射私网IP,成功实现文件上传。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在通过javaApi上传本地文件时出现以下错误,主要原因是:

File /test3.txt could only be written to 0 of the 1 minReplication nodes. There are 1 datanode(s) running and 1 node(s) are excluded in this operation.

org.apache.hadoop.ipc.RemoteException(java.io.IOException): File /test3.txt could only be written to 0 of the 1 minReplication nodes. There are 1 datanode(s) running and 1 node(s) are excluded in this operation.
	at org.apache.hadoop.hdfs.server.blockmanagement.BlockManager.chooseTarget4NewBlock(BlockManager.java:2329)
	at org.apache.hadoop.hdfs.server.namenode.FSDirWriteFileOp.chooseTargetForNewBlock(FSDirWriteFileOp.java:294)
	at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getAdditionalBlock(FSNamesystem.java:2942)
	at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.addBlock(NameNodeRpcServer.java:915)
	at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.addBlock(ClientNamenodeProtocolServerSideTranslatorPB.java:593)
	at org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$ClientNamenodeProtocol$2.callBlockingMethod(ClientNamenodeProtocolProtos.java)
	at org.apache.hadoop.ipc.ProtobufRpcEngine2$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine2.java:600)
	at org.apache.hadoop.ipc.ProtobufRpcEngine2$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine2.java:568)
	at org.apache.hadoop.ipc.ProtobufRpcEngine2$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine2.java:552)
	at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:1093)
	at org.apache.hadoop.ipc.Server$RpcCall.run(Server.java:1035)
	at org.apache.hadoop.ipc.Server$RpcCall.run(Server.java:963)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.Subject.doAs(Subject.java:422)
	at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1878)
	at org.apache.hadoop.ipc.Server$Handler.run(Server.java:2966)


	at org.apache.hadoop.ipc.Client.getRpcResponse(Client.java:1573)
	at org.apache.hadoop.ipc.Client.call(Client.java:1519)
	at org.apache.hadoop.ipc.Client.call(Client.java:1416)
	at org.apache.hadoop.ipc.ProtobufRpcEngine2$Invoker.invoke(ProtobufRpcEngine2.java:242)
	at org.apache.hadoop.ipc.ProtobufRpcEngine2$Invoker.invoke(ProtobufRpcEngine2.java:129)
	at com.sun.proxy.$Proxy14.addBlock(Unknown Source)
	at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.addBlock(ClientNamenodeProtocolTranslatorPB.java:530)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:422)
	at org.apache.hadoop.io.retry.RetryInvocationHandler$Call.invokeMethod(RetryInvocationHandler.java:165)
	at org.apache.hadoop.io.retry.RetryInvocationHandler$Call.invoke(RetryInvocationHandler.java:157)
	at org.apache.hadoop.io.retry.RetryInvocationHandler$Call.invokeOnce(RetryInvocationHandler.java:95)
	at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:359)
	at com.sun.proxy.$Proxy15.addBlock(Unknown Source)
	at org.apache.hadoop.hdfs.DFSOutputStream.addBlock(DFSOutputStream.java:1084)
	at org.apache.hadoop.hdfs.DataStreamer.locateFollowingBlock(DataStreamer.java:1898)
	at org.apache.hadoop.hdfs.DataStreamer.nextBlockOutputStream(DataStreamer.java:1700)
	at org.apache.hadoop.hdfs.DataStreamer.run(DataStreamer.java:707)

但是之前还能解决向hdfs创建目录,为什么不能上传文件嘞?按理说权限不应该有问题,那具体是什么原因,这里通过百度,很多人说是因为

hadoop namenode -format格式化时格式化了多次造成那么spaceID不一致,说要重新格式化启动集群,貌似好像不是这个原因,这边表示很生气。

具体原因在我看到这位大哥的博客之后,立马懂了,在这里感谢大哥,附一下大哥的网址

HDFS服务器使用命令可以上传文件,但客户端上传失败问题File ~ could only be written to 0 of the 1 minReplication nodes._迷雾总会解的博客-优快云博客

根据大哥的见解好像是

NameNode节点存放的是文件目录,也就是文件夹、文件名称,本地可以通过公网访问 NameNode,所以可以进行文件夹的创建,当上传文件需要写入数据到DataNode时,NameNode 和DataNode 是通过局域网进行通信,NameNode返回地址为 DataNode 的私有 IP,本地无法访问

这里也可以看出大哥也使用的是服务器,根据上述理解我们知道因为我们使用的服务器,官方给我们提供的是可以访问的公网,但是内部名称节点和数据节点的通信是通过私网,也就是相当于;老师们经常讲的在一个机架上的各个服务器,它们有一个自己的局域网,而我们本机是无法访问的,明白这个道理之后我们就可以操作了

具体解决步骤

1)首先配置java代码,设置configuration

Configuration conf = new Configuration();
conf.set("dfs.client.use.datanode.hostname", "true");//添加此配置信息即可
FileSystem fs = FileSystem.get(new URI("hdfs://host:9000"), conf, "root");

2)设置完成之后,我们需要找到那个私网ip

在你的服务器上,输入以下指令

   hadoop dfsadmin -report


 

 3)本地还需要配置一下DNS域名映射,在C:\Windows\System32\drivers\etc的hosts文件中配置

        阿里云等服务器还需要配置一下我们的安全组 开放9866端口

 注意:在这边建议把原文件复制一份到外面操作,完成之后再粘贴回来

开放端口

展示最终代码

package com.zhy.hdfs;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;


public class HdfsClient {
    FileSystem fs=null;
    @Before
    public void init() throws URISyntaxException, IOException, InterruptedException {
        Configuration configuration=new Configuration();
        configuration.set("dfs.client.use.datanode.hostname","true");
        //2.根据configuration获取Filesystem对象
        fs=FileSystem.get(new URI("hdfs://你的ip:9000"),configuration,"root");

    }
    @After
    public void destory() throws IOException {
        //4.释放FileSystem对象(类似数据库连接)
        fs.close();
    }



    @Test
    public void testMkdirs() throws URISyntaxException, IOException, InterruptedException {

        fs.mkdirs(new Path("/api_test2"));

    }
    //上传文件
    @Test
    public void copyFromLocalToHdfs() throws URISyntaxException, IOException, InterruptedException {
        //上传文件
        //src:源文件目录:本地路径
        //dst:目标文件目录:hdfs路径
        fs.copyFromLocalFile(new Path("d:/test.txt"),new Path("/test3.txt"));

    }


}

结果展示

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值