200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > Hadoop学习(2)Eclipse配置Hadoop开发环境+HDFS Java API测试+Bug解决记录

Hadoop学习(2)Eclipse配置Hadoop开发环境+HDFS Java API测试+Bug解决记录

时间:2023-06-09 06:38:01

相关推荐

Hadoop学习(2)Eclipse配置Hadoop开发环境+HDFS Java API测试+Bug解决记录

目录

参考:

1. 添加插件

2. 在Windows上安装Hadoop2.9.1

(1)在本地安装Hadoop

(2)配置Hadoop的环境变量

(3)修改hadoop-env.cmd文件中的JAVA_HOME

(4)添加Windows支持文件(winutils.exe,hadoop.dll)

(5)重启Eclipse(File->Restart)

3. Eclipse中的配置

4. 创建HDFS测试项目(Maven工程)

测试代码1:

(1)错误1:

(2)错误2:

(3)错误3:

(4)错误4:

问题总结:

测试代码2:

测试代码3:

测试代码4:

测试代码5:

copyToLocalFile方法报错:

参考:

/qingyunzong/p/8528134.html

1. 添加插件

下载在Windows Eclipse上需要的一些额外的文件:hadoop-eclipse=plugin-2.7.3.jar、winutils.exe,hadoop.dll,下载地址为链接:/s/1XpQ4qXGN4XzgwLNsraDKpQ 密码:obej,然后将hadoop-eclipse=plugin-2.7.3.jar包,并放入到eclipse的plugins文件夹中。

2. 在Windows上安装Hadoop2.9.1

(1)在本地安装Hadoop

我的Hadoop集群版本也是2.9.1(本地与集群版本最好一致)。将之前搭建集群所用的hadoop-2.9.1.tar.gz解压到Windows某目录下,我的是:E:\softwares\hadoop\hadoop-2.9.1,如下:

(2)配置Hadoop的环境变量

HADOOP_HOME=E:\softwares\hadoop\hadoop-2.9.1

Path=E:\softwares\hadoop\hadoop-2.9.1\bin

(3)修改hadoop-env.cmd文件中的JAVA_HOME

hadoop-env.cmd文件在hadoop的安装目录E:\softwares\hadoop\hadoop-2.9.1\下的etc\hadoop\下,我的JAVA_HOME是:C:\Program Files\Java\jdk1.8.0_144。修改完hadoop-env.cmd文件中的JAVA_HOME测试,查看hadoop版本:

经查证,是在hadoop-env.cmd中写JAVA_HOME的路径中出现了问题,本来路径确实是C:\Program Files\Java\jdk1.8.0_144,但路径名称“Program Files”中有空格导致了出错,解决方法如下:

解决参考:

发现原来是路径上包含了一个空格,所以有以下2个解决办法:

1.用路径替代符 C:\Progra~1\Java\jdk1.8.0_144,Progra~1是 C:\Program Files目录的dos文件名模式下的缩写,长于8个字符的文件名和文件夹名,都被简化成前面6个有效字符,后面~1,有重名的就 ~2,~3。

2.用引号括起来 "C:\Program Files"\Java\jdk1.8.0_144

参考:/wen3011/article/details/54907731

根据上面的思路,将hadoop-env.cmd中的JAVA_HOME的路径设置成C:\Progra~1\Java\jdk1.8.0_144,如下:

然后运行hadoop version,成功显示版本信息:

(4)添加Windows支持文件(winutils.exe,hadoop.dll)

1)winutils.exe 放在windows平台中你安装的hadoop的bin目录下2) hadoop.dll 放在windows操作系统的 c:/windows/system32目录下

(5)重启Eclipse(File->Restart)

出现问题:点击如下田字格图标,并没有出现“小象”Map/Reduce的图标:

点击Windows-->Preferences查看,也未出现Hadoop Map/Reduce。

解决参考:

这种现象一般由于安装在eclipse\plugins下的插件没有导入的问题。解决方法:把 eclipse\configuration\org.eclipse.update 删除掉。出现这种情况的原因是在你安装新的插件以前你启动过 eclipse ,在 org.eclipse.update 文件夹下记录了插件的历史更新情况,它只记忆了以前的插件更新情况,而你新安装的插件它并不记录。

参考:/qq_30879741/article/details/72934480

根据上面的思路,我将E:\Eclipse\java-photon\eclipse\configuration\org.eclipse.update\下原先的文件platform.xml删掉,然后重启Eclipse(File->Restart),这次小象的图标就出现了,而且在Window-->Preferences下也出现了Hadoop Map/Reduce。

删掉,然后重启Eclipse,点击右上角“田字格"图标,出现“小象”Map/Reduce的图标,如下(网上有很多说eclipse版本的问题,很多删除eclipse重装的,我觉得此方法太暴力,可能不是版本问题,就是这个org.eclipse.update的问题,它没有及时更新eclipse的变化。我的eclipse版本:Photon Release (4.8.0)):

点击Window-->Preferences查看,出现Hadoop Map/Reduce:

3. Eclipse中的配置

(1)点击Window->Preferences->Hadoop Map/Reduce,设置Hadoop的安装目录:E:\softwares\hadoop\hadoop-2.9.1

(2)打开Hadoop开发视图:Window->Perspective->Open Perspective->Other...,在出现的如下对话框中选择小象Map/Reduce

然后右上角会出现小象图标,以表示是Hadoop开发的视图(Perspective)(以后可直接点击这里的小象图标切换到Hadoop开发视图中):

(3)打开Map/Reduce Locations,Window->Show view->Other...,出现如下弹窗,然后选择MapReduce Tools下的Map/Reduce Locations:

选择后eclipse左侧的Project Explorer会出现左侧的DFS Locations,同时也会出现Map/Reduce Locations的view,如下:

新建Hadoop连接:在上图说显示的Map/Reduce Locations的view中右键,选择New Hadoop Location...,出现如下弹框,然后填写相关配置信息:

配置成功后左侧的DFS Locations显示如下:

而这正与我的Hadoop HDFS的目录结构一致:

4. 创建HDFS测试项目(Maven工程)

测试代码1:

package demo.MavenTest;import .URI;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.FileStatus;import org.apache.hadoop.fs.FileSystem;import org.apache.hadoop.fs.Path;public class HdfsClientTest {public static void main(String[] args) throws Exception{// TODO Auto-generated method stubConfiguration conf = new Configuration();FileSystem fs = FileSystem.get(new URI("hdfs://10.10.129.200:9000"), conf, "hadoop");//测试查看HDFS根目录FileStatus[] listStatus = fs.listStatus(new Path("/"));for (FileStatus fileStatus : listStatus) {System.out.println(fileStatus);}//end forfs.close();}//end main}//end class

对应的pom依赖如下:

<!-- /artifact/org.apache.hadoop/hadoop-common --><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>2.9.1</version></dependency><!-- /artifact/org.apache.hadoop/hadoop-hdfs --><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-hdfs</artifactId><version>2.9.1</version></dependency>

运行程序:(Runas->Run on hadoop)

(1)错误1:

Exception in thread "main" java.lang.NoClassDefFoundError: com/ctc/wstx/io/InputBootstrapper

解决:添加pom依赖(参考:/p/38630695):

<!-- /artifact/com.fasterxml.woodstox/woodstox-core --><dependency><groupId>com.fasterxml.woodstox</groupId><artifactId>woodstox-core</artifactId><version>5.0.3</version></dependency>

保存后重新运行,出现错误2:

(2)错误2:

Exception in thread "main" java.lang.NoClassDefFoundError:org/apache/commons/collections/map/UnmodifiableMap

解决:添加pom依赖:

<!-- /artifact/commons-collections/commons-collections --><dependency><groupId>commons-collections</groupId><artifactId>commons-collections</artifactId><version>3.2.2</version></dependency>

保存后重新运行,出现错误3:

(3)错误3:

Exception in thread "main" java.lang.NoClassDefFoundError:org/apache/commons/configuration/Configuration

解决:添加pom依赖:

<!-- /artifact/commons-configuration/commons-configuration --><dependency><groupId>commons-configuration</groupId><artifactId>commons-configuration</artifactId><version>1.6</version></dependency>

保存后重新运行,出现错误4:

(4)错误4:

Exception in thread "main" java.lang.NoClassDefFoundError:org/apache/hadoop/util/PlatforName

解决:添加pom依赖(参考:/Xgx120413/article/details/51889743):

<!-- /artifact/org.apache.hadoop/hadoop-auth --><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-auth</artifactId><version>2.9.1</version></dependency>

保存后重新运行,程序执行成功:

问题总结:

按说添加了hadoop-common和hadoop-hdfs后,其相应的一些依赖都会下载到本地mvn库,可能在下载时有漏掉一些依赖,每个人这时的错误提示可能有所不一样,但只需要根据错误提示,在pom文件中补上程序运行所需要的依赖即可。我所加入的各个依赖的版本号。是依据于我搭建的Hadoop集群以及Windows本地Hadoop版本来的,查看这些依赖的jar包及版本号,可以在E:\softwares\hadoop\hadoop-2.9.1\share\hadoop\文件夹下的common文件夹和hdfs文件夹查看,例如hdfs文件夹:

这里hdfs文件夹下的jar包是hdfs核心包,在lib文件夹下是其依赖jar包,这些都会需要。在这里可以也查看到相应jar包的版本。

测试代码2:

Configuration conf = new Configuration();FileSystem fs = FileSystem.get(new URI("hdfs://10.10.129.200:9000"), conf, "hadoop");//上传本地文件到HDFSfs.copyFromLocalFile(new Path("C:/Users/a/Desktop/hadoopTest/hello.txt"), new Path("/test/input/javaApiTest.txt"));fs.close();

执行成功,在左侧的DFS Locations里可以看到/test/input/下多了一个文件javaApiTest.txt,其中r3表示有3个副本。

测试代码3:

Configuration conf = new Configuration();FileSystem fs = FileSystem.get(new URI("hdfs://10.10.129.200:9000"), conf, "hadoop");//上传(流式处理,更底层)InputStream in = new FileInputStream(new File("C:/Users/a/Desktop/hadoopTest/hello.txt"));FSDataOutputStream out = fs.create(new Path("/test/input/javaApiTest2.txt"));IOUtils.copyBytes(in, out, 4096, true);fs.close();

执行成功,在左侧的DFS Locations里可以看到/test/input/下多了一个文件javaApiTest2.txt,其中r3表示有3个副本。

测试代码4:

Configuration conf = new Configuration();FileSystem fs = FileSystem.get(new URI("hdfs://10.10.129.200:9000"), conf, "hadoop");//下载(流式处理,更底层)FSDataInputStream in2 = fs.open(new Path("/test/input/words.txt"));OutputStream out2 = new FileOutputStream(new File("C:/Users/a/Desktop/hadoopTest/words2.txt"));IOUtils.copyBytes(in2, out2, 4096, true);fs.close();

执行成功,可看到在C:\Users\a\Desktop\hadoopTest\文件夹下,已经下载下来文件words.txt:

测试代码5:

Configuration conf = new Configuration();FileSystem fs = FileSystem.get(new URI("hdfs://10.10.129.200:9000"), conf, "hadoop");//从HDFS上下载文件到本地fs.copyToLocalFile(new Path("/test/input/words.txt"), new Path("C:/Users/a/Desktop/hadoopTest/words.txt"));fs.close();

copyToLocalFile方法报错:

log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory).log4j:WARN Please initialize the log4j system properly.log4j:WARN See /log4j/1.2/faq.html#noconfig for more info.Exception in thread "main" java.lang.UnsatisfiedLinkError: org.apache.hadoop.io.nativeio.NativeIO$Windows.createFileWithMode0(Ljava/lang/String;JJJI)Ljava/io/FileDescriptor;at org.apache.hadoop.io.nativeio.NativeIO$Windows.createFileWithMode0(Native Method)at org.apache.hadoop.io.nativeio.NativeIO$Windows.createFileOutputStreamWithMode(NativeIO.java:556)at org.apache.hadoop.fs.RawLocalFileSystem$LocalFSFileOutputStream.<init>(RawLocalFileSystem.java:229)at org.apache.hadoop.fs.RawLocalFileSystem$LocalFSFileOutputStream.<init>(RawLocalFileSystem.java:219)at org.apache.hadoop.fs.RawLocalFileSystem.createOutputStreamWithMode(RawLocalFileSystem.java:314)at org.apache.hadoop.fs.RawLocalFileSystem.create(RawLocalFileSystem.java:302)at org.apache.hadoop.fs.RawLocalFileSystem.create(RawLocalFileSystem.java:334)at org.apache.hadoop.fs.ChecksumFileSystem$ChecksumFSOutputSummer.<init>(ChecksumFileSystem.java:399)at org.apache.hadoop.fs.ChecksumFileSystem.create(ChecksumFileSystem.java:462)at org.apache.hadoop.fs.ChecksumFileSystem.create(ChecksumFileSystem.java:441)at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:1067)at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:1048)at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:937)at org.apache.hadoop.fs.FileUtil.copy(FileUtil.java:391)at org.apache.hadoop.fs.FileUtil.copy(FileUtil.java:364)at org.apache.hadoop.fs.FileUtil.copy(FileUtil.java:314)at org.apache.hadoop.fs.FileSystem.copyToLocalFile(FileSystem.java:2375)at org.apache.hadoop.fs.FileSystem.copyToLocalFile(FileSystem.java:2344)at org.apache.hadoop.fs.FileSystem.copyToLocalFile(FileSystem.java:2320)at demo.MavenTest.HdfsClientTest.main(HdfsClientTest.java:52)

查看copyToLocalFile的源码:

public void copyToLocalFile(Path src, Path dst) throws IOException {copyToLocalFile(false, src, dst);}

继续跟踪:

public void copyToLocalFile(boolean delSrc, Path src, Path dst)throws IOException {copyToLocalFile(delSrc, src, dst, false);}

继续跟踪:

/*** The src file is under this filesystem, and the dst is on the local disk.* Copy it from the remote filesystem to the local dst name.* delSrc indicates if the src will be removed* or not. useRawLocalFileSystem indicates whether to use RawLocalFileSystem* as the local file system or not. RawLocalFileSystem is non checksumming,* So, It will not create any crc files at local.** @param delSrc*whether to delete the src* @param src*path* @param dst*path* @param useRawLocalFileSystem*whether to use RawLocalFileSystem as local file system or not.** @throws IOException for any IO error*/public void copyToLocalFile(boolean delSrc, Path src, Path dst,boolean useRawLocalFileSystem) throws IOException {Configuration conf = getConf();FileSystem local = null;if (useRawLocalFileSystem) {local = getLocal(conf).getRawFileSystem();} else {local = getLocal(conf);}FileUtil.copy(this, src, local, dst, delSrc, conf);}

参数1->delSrc表示:是否要深处源文件;

参数2->src表示:要copy的源文件路径;

参数3->dst表示:copy的目标文件路径;

参数4->useRawLocalFileSystem表示:注释上说useRawLocalFileSystem指示是否使用RawLocalFileSystem作为本地文件系统。

关于参数useRawLocalFileSystem的解释网上找了主要有2种:

第1种是参考/hdfs-java-api-%E8%AF%A6%E8%A7%A3/,说如果这个值为真,就会调用一个getRawFileSystem()方法,API上说这个方法将会返回一个本地文件系统。默认是使用HDFS的文件系统,如果是windows系统,需要使用原生的本地文件系统。第2种是参考/u014432433/article/details/51479720,原文如下:

hadoop是一个综合文件系统,并不等价于hdfs文件系统。hadoop集成了众多的文件系统, hdfs仅仅是hadoop旗舰级文件系统。Hadoop的这个特点充分体现了hadoop的优良的可扩展性。在hadoop里,hadoop定义了一个抽象的文件系统的概念,类:org.apache.hadoop.fs.FileSystm,这个抽象类用来定义hadoop中的一个文件系统接口,只要某个文件系统实现了这个接口,就可以作为hadoop支持的文件系统。

Hadoop LocalFileSystem是客户端校验的类。在使用LocalFileSystem写文件时,会透明的创建一个.filename.crc的文件。 校验文件大小的字节数由io.bytes.per.checksum属性设置,默认是512bytes,即每512字节就生成一个CRC-32校验和。.filename.crc文件会存 io.bytes.per.checksum的信息。在读取的时候,会根据此文件进行校验。事实上LocalFileSystem是通过继承ChecksumFileSystem实现校验的工作。

从上面内容可知,当设置useRawLocalFileSystem为true时就是指使用Hadoop LocalFileSystem,即开启校验。所以参数useRawLocalFileSystem就是表示是否开启文件校验。

解决:将代码 fs.copyToLocalFile(new Path("/test/input/words.txt"), new Path("C:/Users/a/Desktop/hadoopTest/words.txt"));改为 fs.copyToLocalFile(false, new Path("/test/input/words.txt"), new Path("C:/Users/a/Desktop/hadoopTest/words.txt"),true);后程序即可执行成功,在C:\Users\a\Desktop\hadoopTest\文件夹下多了文件words.txt。

Configuration conf = new Configuration();FileSystem fs = FileSystem.get(new URI("hdfs://10.10.129.200:9000"), conf, "hadoop");//从HDFS上下载文件到本地//fs.copyToLocalFile(new Path("/test/input/words.txt"), new Path("C:/Users/a/Desktop/hadoopTest/words.txt"));fs.copyToLocalFile(false, new Path("/test/input/words.txt"), new Path("C:/Users/a/Desktop/hadoopTest/words.txt"), true);fs.close();

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。