问题描述
阿里云服务器命令行使用命令可以上传文件,但HDFS java API上传失败,上传后只有文件名没有数据
报错: 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
解决思路
Hadoop的NameNode节点和DataNode节点之间是使用内网IP通信的,所以不管我们配置单机伪分布式,还是集群(CDH,HDP...)都是需要配置内网IP和主机名的映射,因为我们外网开发环境可以通过外网IP访问NameNode节点,所以创建目录是没问题的,但是文件的内容需要写到DataNode节点上,这时外网是无法和DataNode节点直接通信发数据的(需要了解NameNode和DataNode之间数据的传输机制也就是put和get操作).
解决办法
1.在服务器端配置内网IP和主机名映射,在外网开发机器上配置外网IP和主机名映射(主机名相同)
2.在hdfs-site.xml文件中配置属性
dfs.datanode.use.datanode.hostname
true
<-----------注意需要重启hdfs!!!---------->
3.然后在代码中configuration中配置
configuration.set("dfs.client.use.datanode.hostname", "true");
FileSystem fs = FileSystem.get(new URI("hdfs://hostname:9000"), configuration, "hadoop");
4.还需要注意一点的是Hadoop3版本默认的端口有修改
Namenode 端口:
50470 --> 9871
50070 --> 9870
8020 --> 9820
Secondary NN 端口:
50091 --> 9869
50090 --> 9868
Datanode 端口:
50020 --> 9867
50010 --> 9866
50475 --> 9865
50075 --> 9864
此时需要通过命令(此命令需要HDFS的超级用户使用)
hdfs dfsadmin -report 查看当前datanode的端口(我是使用的伪分布式)
Name: 172.17.111.223:9866 (***这里是主机名***)
Hostname: (***这里是主机名***)
Decommission Status : Normal
Configured Capacity: 105552769024 (98.30 GB)
DFS Used: 49152 (48 KB)
Non DFS Used: 4163235840 (3.88 GB)
DFS Remaining: 96863227904 (90.21 GB)
DFS Used%: 0.00%
DFS Remaining%: 91.77%
Configured Cache Capacity: 0 (0 B)
Cache Used: 0 (0 B)
Cache Remaining: 0 (0 B)
Cache Used%: 100.00%
Cache Remaining%: 0.00%
Xceivers: 1
Last contact: Wed Nov 24 16:47:57 CST 2021
Last Block Report: Wed Nov 24 14:28:35 CST 2021
Num of Blocks: 1
5.需要在阿里云安全组开放刚才查到的端口 9866 此时再运行代码,成功发送数据到HDFS上