平时我们在本地开发的时候,需要测试连接hdfs上传或者下载文件。
可以通过docker在本地快速搭建一个测试的hadoop集群环境。
1.但是在上传文件的时候出现问题:
WARN org.apache.hadoop.hdfs.DFSClient - DataStreamer Exception
org.apache.hadoop.ipc.RemoteException: File xxxxx could only be replicated to 0 nodes instead of minReplication (=1). There are 2 datanode(s) running and no node(s) are excluded in this operation.
at org.apache.hadoop.hdfs.server.blockmanagement.BlockManager.chooseTarget4NewBlock(BlockManager.java:1625)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getNewBlockTargets(FSNamesystem.java:3132)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getAdditionalBlock(FSNamesystem.java:3056)
at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.addBlock(NameNodeRpcServer.java:725)
at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.addBlock(ClientNamenodeProtocolServerSideTranslatorPB.java:493)
at org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$ClientNamenodeProtocol$2.callBlockingMethod(ClientNamenodeProtocolProtos.java)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine.java:616)
at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:982)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:2217)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:2213)
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:1758)
at org.apache.hadoop.ipc.Server$Handler.run(Server.java:2213)
docker集群是没有问题的,可以上传下载文件。
也可以连接查看文件目录。
但是上传文件的时候就报错。
解决方案:
在上传文件的时候,client首先和namenode进行交互,获取到可以存放数据的datanode,然后将datanode的信息返回给client,然后client请求该节点,建立连接,上传数据。
我们在docker里面部署hdfs集群的时候,没有暴露上传文件需要的端口50010,该端口是和datanode交互上传数据的。
因为本地环境只有一台物理机,只能同时暴露一个datanode的50010端口到物理机。所以我们选择其中的一个node进行端口映射到本地。
也可以将master的50010端口映射到本地,添加master ip到slave文件:
![5584341a26bd137c0ba154dd642e70d2.png](https://i-blog.csdnimg.cn/blog_migrate/bba178af10baf095565727dfddaa6d90.png)
2.映射了端口后,出现timeout错误
![d8dc4f694fcf80fe3d7140524d04b566.png](https://i-blog.csdnimg.cn/blog_migrate/87a3a1ef4d3d996a2625922042305c40.png)
该错误使用了docker容器内部的ip 172.18.0.2,该ip在物理机上是没法直接访问的。
解决方案:
在Configuration配置中配置dfs.client.use.datanode.hostname:
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://127.0.0.1:9000/");
conf.set("dfs.client.use.datanode.hostname", "true");
3.本地连接HDFS出现权限问题Permission denied
![86f94de50c3d572c0b9bfbc9aa855327.png](https://i-blog.csdnimg.cn/blog_migrate/a8307dbe7a7d13ff2f8a6731ebcf6b09.png)
解决方案:
System.setProperty("HADOOP_USER_NAME", "root");
如果还有文件目录权限问题:
可以将需要上传的目录设置为777权限:
hdfs dfs -chmod 777 /dir
4.如果出现找不到hadoop文件
System.setProperty("hadoop.home.dir", "/hadoop/hadoop-2.7.7");