阿里云Ubuntu18.04
伪分布式
hadoop3.0.3
问题描述
用java api访问hdfs的文件,拿不到数据。另外,创建文件可以,写数据不行
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.junit.Test;
public class HdfsDemoApp {
@Test
public static void main(String[] args) {
try {
//创建Configuration对象
Configuration conf = new Configuration();
//设置Hadoop的dfs客户端使用hostname访问datanode
//conf.set("dfs.client.use.datanode.hostname", "true");
conf.set("fs.defaultFS", "hdfs://master:9000");
FileSystem fs = FileSystem.get(conf);
// 打开hdfs上的文件并读取输出
Path hello = new Path("/user/hdfs/artist.txt");
FSDataInputStream ins = fs.open(hello);
int ch = ins.read();
while (ch != -1) {
System.out.print((char) ch);
ch = ins.read();
}
System.out.println();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
原因分析:
文件夹和文件名都是存放在 NameNode 上的,本地可以通过公网访问 NameNode,所以创建文件夹和文件都可以,但是写数据的时候,NameNode 和DataNode 是通过内网通信的,NameNode 会返回给本地 DataNode 的内网 IP,本地就访问不了了。
解决方案:让NameNode不返回DataNode的私网IP,而返回的是DataNode的主机名
方案一:在代码中添加配置信息
//创建Configuration对象
Configuration conf = new Configuration();
//设置Hadoop的dfs客户端使用hostname访问datanode
conf.set("dfs.client.use.datanode.hostname", "true");
方案二:修改hdfs-site.xml和core-site.xml并且把这两个配置文件放在IDEA的resources目录下
hdfs-site.xml
only cofig in clients
dfs.client.use.datanode.hostname
true
core-site.xml
hadoop.tmp.dir file:/opt/hadoop/tmp fs.defaultFS hdfs://master:9000 hadoop.proxyuser.hadoop.hosts * hadoop.proxyuser.hadoop.groups * dfs.permissions.enabled false
在阿里云的防火墙添加规则,手动添加DataNode用于数据传输服务端口 默认是 9866(hadoop3.0之前的端口是50010)。
附上hadoop3.x的端口变化:
Namenode ports: 50470 --> 9871, 50070 --> 9870, 8020 --> 9820
Secondary NN ports: 50091 --> 9869, 50090 --> 9868
Datanode ports: 50020 --> 9867, 50010 --> 9866, 50475 --> 9865, 50075 --> 9864
最后配置本地host映射
hosts文件在Windows下的路径为:
C:WindowsSystem32driversetchosts
在文件中添加
公网IP 主机名(我的是master)



