0. 相关文章链接
问题1:不能写入数据到HDFS中(There are 1 datanode(s) running and 1 node(s) are excluded in this operation.)
如前面数据湖之Hudi系列文章,能通过Spark代码对Hudi进行增删改查(本质是将数据存储在HDFS上,然后使用Spark对HDFS进行操作)
但前面操作都是将服务器在本地通过VMware安装虚拟机,然后通过idea编写代码,运行程序
这次博主在华为云上新建了一台Centos7.9的服务器,打算对其中的数据进行操作
先根据前面教程 数据湖之Hudi(6):Hudi与Spark和HDFS的集成安装使用 安装开发环境,然后直接在服务器上通过spark-shell命令进行hudi的操作,发现一切正常
然后打算在本地运行idea程序,对云服务器上的hudi(也就是hdfs)进行操作,然后发现报如下异常
Exception in thread "main" org.apache.hadoop.ipc.RemoteException(java.io.IOException): File /hudi-warehouse/tbl_trips_cow/.hoodie/hoodie.properties 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:2205)
at org.apache.hadoop.hdfs.server.namenode.FSDirWriteFileOp.chooseTargetForNewBlock(FSDirWriteFileOp.java:294)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getAdditionalBlock(FSNamesystem.java:2731)
at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.addBlock(NameNodeRpcServer.java:892)
at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.addBlock(ClientNamenodeProtocolServerSideTranslatorPB.java:568)
at org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$ClientNamenodeProtocol$2.callBlockingMethod(ClientNamenodeProtocolProtos.java)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine.java:527)
at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:1036)
at org.apache.hadoop.ipc.Server$RpcCall.run(Server.java:1000)
at org.apache.hadoop.ipc.Server$RpcCall.run(Server.java:928)
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:1729)
at org.apache.hadoop.ipc.Server$Handler.run(Server.java:2916)
at org.apache.hadoop.ipc.Client.getRpcResponse(Client.java:1545)
at org.apache.hadoop.ipc.Client.call(Client.java:1491)
at org.apache.hadoop.ipc.Client.call(Client.java:1388)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:233)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:118)
at com.sun.proxy.$Proxy30.addBlock(Unknown Source)
at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.addBlock(ClientNamenodeProtocolTranslatorPB.java:514)
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.$Proxy31.addBlock(Unknown Source)
at org.apache.hadoop.hdfs.DFSOutputStream.addBlock(DFSOutputStream.java:1081)
at org.apache.hadoop.hdfs.DataStreamer.locateFollowingBlock(DataStreamer.java:1866)
at org.apache.hadoop.hdfs.DataStreamer.nextBlockOutputStream(DataStreamer.java:1668)
at org.apache.hadoop.hdfs.DataStreamer.run(DataStreamer.java:716)
通过上述保存可以看出,不是hudi报错,就是hadoop报错,也就是不能将数据写入到hdfs中
然后上hdfs的web页面细看,发现可以创建文件夹,创建文件,但是就不能将数据写入进去
一下就卡住了,没办法,只能上网找资料,网上乱七八糟什么都有,什么服务器防火墙没关(云服务器的防火墙本来就是关的),什么云服务器的安全组没打开(如果没打开怎么能创建文件夹并在本地访问呢),什么NameNode和DataNode的clusterID不一致(非常确定一致),什么将各个服务关了重开(试过,没用),什么重新格式化NameNode(都重装服务器系统了,还是没用),那没得办法,只能继续找资料
终于被我找到了,发现是要在hdfs-site.xml 配置客户端用hostname方式访问集群,于是解决办法就是 在所有节点上 修改 hdfs-site.xml ,添加如下配置:
<property>
<name>dfs.client.use.datanode.hostname</name>
<value>true</value>
<description>only cofig in clients</description>
</property>
如果还不能成功,需要在java或者scala代码中添加如下代码:
Configuration configuration=new Configuration();
configuration.set("dfs.client.use.datanode.hostname", "true");
FileSystem fileSystem=FileSystem.get(new URI("hdfs://yangshibiao:8020"),configuration,"hadoop");
这是因为博主的Hadoop集群都部署在华为云上,集群默认会返回内网ip列表,所以需要设置dfs.client.use.datanode.hostname=true
另外还有,请注意,当在本地调试程序,对hdfs进行操作时,需要将 hdfs-site.xml 和 core-site.xml 这2个配置拷贝到本地的 resources 文件夹下,这样才能像在服务器上一样对hdfs进行操作
到这里问题终于完美解决了,出坑了,卡了一整天,还以为是其他什么问题,真开心
程序运行成功截图如下:
未完待续......
注:Hudi系列博文为通过对Hudi官网学习记录所写,其中有加入个人理解,如有不足,请各位读者谅解☺☺☺
注:其他相关文章链接由此进(包括Hudi在内的各数据湖相关博文) -> 数据湖 文章汇总