本文共 3773 字,大约阅读时间需要 12 分钟。
之前分别介绍了和,在介绍Java访问方式时(C API不存在这样的问题),程序是部署在Hadoop安装环境的,这具有一定的局限性,因为客户端不可能总是运行在Hadoop安装节点上。本文介绍以Java方式远程访问/操作HDFS。
在Hadoop安装环境中和远程访问的主要区别在于Hadoop环境配置的获取和程序的执行方式。
在前续的文章中,将客户端打成jar包后,使用”hadoop jar xx.jar”来运行。而远程访问时,由于客户端运行环境并未安装Hadoop,因此只能以java的方式运行程序。 在Hadoop安装环境下:Configuration conf = new Configuration(); //获取当前的默认环境配置FileSystem fs = FileSystem.get(conf); //根据当前环境配置,获取文件系统访问实例
上述代码,在使用hadoop命令运行时,便可以自动获取hadoop安装环境中的配置,如hdfs-site.xml中配置。
在未安装Hadoop的客户端上,必须手动配置需要的环境变量才能正确访问,例如在前续文章的单节点环境中,需要手动配置一下环境:Configuration conf = new Configuration();conf.set("fs.defaultFS", "hdfs://{IP}:9000");conf.set("fs.hdfs.impl","org.apache.hadoop.hdfs.DistributedFileSystem");conf.set("dfs.client.block.write.replace-datanode-on-failure.policy", "NEVER");FileSystem fs = FileSystem.get(conf);
在获取了FileSystem访问实例后,之后的文件系统操作都和之前相同,在此不再累述。
程序的运行
如前所述,不能再以hadoop来运行程序,可以通过:java -classpath $RemoteHDFSTest {main class}
RemoteHDFSTest是自定义的,程序运行依赖的jar包组成的环境变量,如:RemoteHDFSTest=.:hadoop-common-2.7.3.jar:….
可能出现的异常:
1.未配置远程访问地址”dfs.namenode.rpc-address”Exception in thread "main" java.net.ConnectException: Call From master/192.168.**.** to master:9000 failed on connection exception: java.net.ConnectException: Connection refused; For more details see: http://wiki.apache.org/hadoop/ConnectionRefused at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.apache.hadoop.net.NetUtils.wrapWithMessage(NetUtils.java:792) at org.apache.hadoop.net.NetUtils.wrapException(NetUtils.java:732) at org.apache.hadoop.ipc.Client.call(Client.java:1479)
解决方法:在hadoop安装环境,hdfs-site.xml中增加:
dfs.namenode.rpc-address 192.168.**.**:9000
2.单节点安装,只有一个datanode,默认replace-datanode-on-failure.policy是DEFAULT,如果系统中的datanode大于等于1,它会找另外一个datanode来拷贝。目前机器只有1台,因此只要一台datanode出问题,就一直无法写入成功。需要配置出现此种情况应该采取的策略
Exception in thread "main" java.io.IOException: Failed to replace a bad datanode on the existing pipeline due to no more good datanodes being available to try. (Nodes: current=[DatanodeInfoWithStorage[192.168.94.200:50010,DS-a3fffc75-b30f-45c7-b976-86347fe90a10,DISK]], original=[DatanodeInfoWithStorage[192.168.94.200:50010,DS-a3fffc75-b30f-45c7-b976-86347fe90a10,DISK]]). The current failed datanode replacement policy is DEFAULT, and a client may configure this via 'dfs.client.block.write.replace-datanode-on-failure.policy' in its configuration. at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.findNewDatanode(DFSOutputStream.java:914) at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.addDatanode2ExistingPipeline(DFSOutputStream.java:988) at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.setupPipelineForAppendOrRecovery
解决方法:在客户端中增加配置
conf.set("dfs.client.block.write.replace-datanode-on-failure.policy", "NEVER");
3.HA配置
在生产环境中,通常Hadoop的安装都配置了nameservices(参见文章: ),并且开启了主备切换,那么环境的设置可以参考如下:Configuration conf = new Configuration();conf.set("fs.defaultFS", "hdfs://testcluster"); conf.set("dfs.nameservices","testcluster"); //假设nameservices命名为testclusterconf.set("dfs.ha.namenodes.testcluster","nn1,nn2");conf.set("dfs.namenode.rpc-address.testcluster.nn1","192.168.**.**:8020");conf.set("dfs.namenode.rpc-address.testcluster.nn2","192.168.**.**:8020");conf.set("dfs.client.failover.proxy.provider.testcluster","org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider");FileSystem fs = FileSystem.get(conf);
综上,远程客户端访问HDFS的环境配置,应该参考Hadoop安装环境的实际配置,参考安装环境中core-site.xml,hdfs-site.xml…中的配置来设置Configuration。
转载地址:http://zkbmb.baihongyu.com/