我们是在Hadoop伪分布式下去进行HDFS的编程实践
准备工作:
vm15.5
hadoop3.3.1
eclipse-java-2021-09-R-linux-gtk-x86_64
参考:林子雨:HDFS编程实践(Hadoop3.1.3)_厦大数据库实验室博客
他使用的是Hadoop3.1.3版本的,过程可能会遇到的坑将在另一篇文章中总结:在进行HDFS实践时遇到的问题:_阿洋太爱大数据的博客
开始
在HDFS编程实践前,我们需要启动Hadoop(版本是Hadoop3.1.3)。
执行如下命令:
cd /usr/local/hadoop
./sbin/start-dfs.sh
并且jps
检查是否启动成功:
[hadoop@localhost hadoop]$ jps
5233 SecondaryNameNode
5382 Jps
5018 DataNode
4893 NameNode
成功后开始我们的实践
一、利用Shell命令与HDFS进行交互
在终端输入如下命令,查看fs总共支持了哪些命令
[hadoop@localhost hadoop]$ ./bin/hadoop fs
在终端输入如下命令,可以查看具体某个命令的作用
例如:我们查看rm命令如何使用,可以输入如下命令
./bin/hadoop fs -help rm
1、目录操作
Hadoop系统安装好以后,第一次使用HDFS时,需要首先在HDFS中创建用户目录。我们在这里采用hadoop用户登录Linux系统,因此,需要在HDFS中为hadoop用户创建一个用户目录,命令如下:
cd /usr/local/hadoop
./bin/hdfs dfs -mkdir -p /user/hadoop
该命令中表示在HDFS中创建一个“/user/hadoop”目录,“–mkdir”是创建目录的操作,“-p”表示如果是多级目录,则父目录和子目录一起创建,这里“/user/hadoop”就是一个多级目录,因此必须使用参数“-p”,否则会出错。 “/user/hadoop”目录就成为hadoop用户对应的用户目录,可以使用如下命令显示HDFS中与当前用户hadoop对应的用户目录下的内容:
[hadoop@localhost hadoop]$ ./bin/hdfs dfs -ls #该命令中,“-ls”表示列出HDFS某个目录下的所有内容,“.”表示HDFS中的当前用户目录,也就是“/user/hadoop”目录,因此,上面的命令和下面的命令是等价的:
[hadoop@localhost hadoop]$ ./bin/hdfs dfs -ls /user/hadoop
#如果要列出HDFS上的所有目录,可以使用如下命令:
[hadoop@localhost hadoop]$ ./bin/hdfs dfs -ls
#下面,可以使用如下命令创建一个input目录:
[hadoop@localhost hadoop]$ ./bin/hdfs dfs -mkdir input
#在创建个input目录时,采用了相对路径形式,实际上,这个input目录创建成功以后,它在HDFS中的完整路径是“/user/hadoop/input”
可以使用rm命令删除一个目录,比如,可以使用如下命令删除刚才在HDFS中创建的“/input”目录(不是“/user/hadoop/input”目录):
./bin/hdfs dfs –rm –r /input #“-r”参数表示如果删除“/input”目录及其子目录下的所有内容,如果要删除的一个目录包含了子目录,则必须使用“-r”参数,否则会执行失败。
2.文件操作
在实际应用中,经常需要从本地文件系统向HDFS中上传文件,或者把HDFS中的文件下载到本地文件系统中。 首先,使用vim编辑器,在本地Linux文件系统的“/home/hadoop/”目录下创建一个文件myLocalFile.txt,里面可以随意输入一些单词
[hadoop@localhost ~]$ cd /home
[hadoop@localhost home]$ cd /home/hadoop
[hadoop@localhost ~]$ pwd
/home/hadoop
[hadoop@localhost ~]$ vim myLocalFile.txt
然后,可以使用如下命令把本地文件系统的“/home/hadoop/myLocalFile.txt”上传到HDFS中的当前用户目录的input目录下,也就是上传到HDFS的“/user/hadoop/input/”目录下:(注意路径)
[hadoop@localhost ~]$ cd /usr/local/hadoop
[hadoop@localhost hadoop]$ ./bin/hdfs dfs -put /home/hadoop/myLocalFile.txt input
可以使用ls命令查看一下文件是否成功上传到HDFS中,具体如下:
[hadoop@localhost hadoop]$ ./bin/hdfs dfs -ls input
下面使用如下命令查看HDFS中的myLocalFile.txt这个文件的内容:
./bin/hdfs dfs –cat input/myLocalFile.txt
下面把HDFS中的myLocalFile.txt文件下载到本地文件系统中的“/home/hadoop/下载/”这个目录下,命令如下:
./bin/hdfs dfs -get input/myLocalFile.txt /home/hadoop/下载
[hadoop@localhost hadoop]$ cd ~
[hadoop@localhost ~]$ cd 下载
[hadoop@localhost 下载]$ ls
hadoop-3.3.1.tar.gz myLocalFile.txt
[hadoop@localhost 下载]$ cat myLocalFile.txt
最后,了解一下如何把文件从HDFS中的一个目录拷贝到HDFS中的另外一个目录。比如,如果要把HDFS的“/user/hadoop/input/myLocalFile.txt”文件,拷贝到HDFS的另外一个目录“/input”中(注意,这个input目录位于HDFS根目录下),可以使用如下命令:
./bin/hdfs dfs -cp input/myLocalFile.txt /input
二、利用Web界面管理HDFS
通过浏览器访问:http://localhost:9870
三、利用JAVA API与HDFS进行交互
(一)安装eclipse:
1在centos7中安装eclipse
下载地址:Luna SR2 | Eclipse Packages
2.通过xftp来传输
a)先在Windows环境下下载好文件Luna SR2 | Eclipse Packages选择正确的文件
b)通过xftp远程登录虚拟机来传输文件
名称自定,主机为虚拟机的IP地址(通过ifconfig来查看),用户名为hadoop,密码为自己虚拟机用户的密码,然后点击连接
然后将下载好的eclipse压缩包通过拖拽的方式拖到想要的目录下,此处为下载目录
c)在虚拟机内解压缩eclipse压缩包
已经通过xftp完成了eclipse压缩包的传输,在下载目录下ls查看是否成功:
[hadoop@localhost 下载]$ ls
eclipse-java-2021-09-R-linux-gtk-x86_64.tar.gz hadoop-3.3.1.tar.gz myLocalFile.txt
出现了目标的压缩包,则已经成功
解压缩:(eclipse-java-2021-09-R-linux-gtk-x86_64.tar.gz为自己的压缩包文件名)
sudo tar -zxvf ./eclipse-java-2021-09-R-linux-gtk-x86_64.tar.gz -C /usr/local
eclipse/
等待片刻后成功,通过如下启动eclipse:
cd /usr/local/eclipse
./eclipse
(二)使用eclipse开发调试HDFS Java程序
1.在eclipse中创建项目:
启动eclipse,出现以下界面:
可以直接采用默认的设置“/home/hadoop/workspace”
进入后:选择“File–>New–>Java Project”菜单,开始创建一个Java工程,会弹出如下图所示界面。
在“Project name”后面输入工程名称“HDFSExample”,选中“Use default location”,让这个Java工程的所有文件都保存到“/home/hadoop/workspace/HDFSExample”目录下。在“JRE”这个选项卡中,可以选择当前的Linux系统中已经安装好的JDK
可以见到我这里是选项Use a project specific JRE选项里面这里是有对应合适的JDK包,但是我刚进去的时候是没有的,需要手动自己配置一下:
点击蓝色字体:Configure JREs...
点击右侧的Add
点击Standard VM后点击next
再弹出的窗口的JRE home处填入自己的Java安装路径,可以在我教程Java安装教程里面找到,简单来说也就是需要配置环境变量这里的这个路径。
完成后finish,退出重新打卡,就有了
点击next,在这个界面中加载该Java工程所需要用到的JAR包,这些JAR包都位于Linux系统的Hadoop安装目录下,即“/usr/local/hadoop/share/hadoop”,点击界面中的“Libraries”选项卡,然后,点击界面右侧的“Add External JARs…”按钮。
先点一下ModulePath,再点Add External JARs...
将以下四个文件夹里面的全部JAR包选择添加(不含文件和目录)。
“/usr/local/hadoop/share/hadoop/common”
“/usr/local/hadoop/share/hadoop/common/lib”
“/usr/local/hadoop/share/hadoop/hdfs”
“/usr/local/hadoop/share/hadoop/hdfs/lib”
导入后:
添加完四个文件夹内的jar包后点击Finish,完成项目创建
2.编写Java应用程序
在Eclipse工作界面左侧的“Package Explorer”面板中,找到刚才创建好的工程名称“HDFSExample”,然后在该工程名称上点击鼠标右键,在弹出的菜单中选择“ New–>Class”菜单
只需要在“Name”后面输入Java类文件的名称“MergeFile”,其余设置默认
在“MergeFile.java”源文件代码写入下代码,先别运行
import java.io.IOException;
import java.io.PrintStream;
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
/**
* 过滤掉文件名满足特定条件的文件
*/
class MyPathFilter implements PathFilter {
String reg = null;
MyPathFilter(String reg) {
this.reg = reg;
}
public boolean accept(Path path) {
if (!(path.toString().matches(reg)))
return true;
return false;
}
}
/***
* 利用FSDataOutputStream和FSDataInputStream合并HDFS中的文件
*/
public class MergeFile {
Path inputPath = null; //待合并的文件所在的目录的路径
Path outputPath = null; //输出文件的路径
public MergeFile(String input, String output) {
this.inputPath = new Path(input);
this.outputPath = new Path(output);
}
public void doMerge() throws IOException {
Configuration conf = new Configuration();
conf.set("fs.defaultFS","hdfs://localhost:9000");
conf.set("fs.hdfs.impl","org.apache.hadoop.hdfs.DistributedFileSystem");
FileSystem fsSource = FileSystem.get(URI.create(inputPath.toString()), conf);
FileSystem fsDst = FileSystem.get(URI.create(outputPath.toString()), conf);
//下面过滤掉输入目录中后缀为.abc的文件
FileStatus[] sourceStatus = fsSource.listStatus(inputPath,
new MyPathFilter(".*\\.abc"));
FSDataOutputStream fsdos = fsDst.create(outputPath);
PrintStream ps = new PrintStream(System.out);
//下面分别读取过滤之后的每个文件的内容,并输出到同一个文件中
for (FileStatus sta : sourceStatus) {
//下面打印后缀不为.abc的文件的路径、文件大小
System.out.print("路径:" + sta.getPath() + " 文件大小:" + sta.getLen()
+ " 权限:" + sta.getPermission() + " 内容:");
FSDataInputStream fsdis = fsSource.open(sta.getPath());
byte[] data = new byte[1024];
int read = -1;
while ((read = fsdis.read(data)) > 0) {
ps.write(data, 0, read);
fsdos.write(data, 0, read);
}
fsdis.close();
}
ps.close();
fsdos.close();
}
public static void main(String[] args) throws IOException {
MergeFile merge = new MergeFile(
"hdfs://localhost:9000/user/hadoop/",
"hdfs://localhost:9000/user/hadoop/merge.txt");
merge.doMerge();
}
}
Hadoop的准备:
确保Hadoop已经启动运行,如果还没有启动,需要打开一个Linux终端,输入以下命令启动Hadoop:
$ cd /usr/local/hadoop
$ ./sbin/start-dfs.sh
在Linux创建5个文件,file1.txt、file2.txt、file3.txt、file4.abc和file5.abc。假设内容如下:(vim 创建,填写内容)
file1.txt的内容是: this is file1.txt
file2.txt的内容是: this is file2.txt
file3.txt的内容是: this is file3.txt
file4.abc的内容是: this is file4.abc
file5.abc的内容是: this is file5.abc
然后将这五个文件转到HDFS(其他文件同理),这里我把5个文件放到了/home//hadoop/下了
通过$ ./bin/hdfs dfs -put file1.txt的路径
[hadoop@localhost bin]$ cd /home/hadoop/
[hadoop@localhost ~]$ vim file2.txt
[hadoop@localhost ~]$ vim file3.txt
[hadoop@localhost ~]$ vim file4.abc
[hadoop@localhost ~]$ vim file5.abc
[hadoop@localhost ~]$ cd /usr/local/hadoop
[hadoop@localhost hadoop]$ ./bin/hdfs dfs -put /home/hadoop/file2.txt
[hadoop@localhost hadoop]$ ./bin/hdfs dfs -put /home/hadoop/file3.txt
[hadoop@localhost hadoop]$ ./bin/hdfs dfs -put /home/hadoop/file4.abc
[hadoop@localhost hadoop]$ ./bin/hdfs dfs -put /home/hadoop/file5.abc
现在可以让代码运行了,在代码旁边右键鼠标,在弹出的菜单中选择“Run As”,继续在弹出来的菜单中选择“Java Application”
应用部署:Java应用程序生成JAR包,部署到Hadoop平台上运行。首先,在Hadoop安装目录下新建一个名称为myapp的目录,用来存放我们自己编写的Hadoop应用程序,可以在Linux的终端中执行如下命令:
[hadoop@localhost hadoop]$ mkdir myapp
[hadoop@localhost hadoop]$ cd ./myapp
然后,请在Eclipse工作界面左侧的“Package Explorer”面板中,在工程名称“HDFSExample”上点击鼠标右键,在弹出的菜单中选择“Export”,如下图所示。
在弹出的界面中选中JAVA,然后选择Runnable JAR file
点击next,然后在该界面中,“Launch configuration”用于设置生成的JAR包被部署启动时运行的主类,需要在下拉列表中选择刚才配置的类“MergeFile-HDFSExample”。在“Export destination”中需要设置JAR包要输出保存到哪个目录,比如,这里设置为“/usr/local/hadoop/myapp/HDFSExample.jar”。在“Library handling”下面选择“Extract required libraries into generated JAR”。
一定要在此路径下
然后一路OK,遇到警告忽略就可
至此,已经顺利把HDFSExample工程打包生成了HDFSExample.jar
可以在Linux的终端中执行如下命令:
[hadoop@localhost hadoop]$ cd /usr/local/hadoop
[hadoop@localhost hadoop]$ cd ./myapp
[hadoop@localhost myapp]$ ls
可以看到,“/usr/local/hadoop/myapp”目录下已经存在一个HDFSExample.jar文件
由于之前已经运行过一次程序,已经生成了merge.txt,因此,需要首先执行如下命令删除该文件:
[hadoop@localhost myapp]$ cd /usr/local/hadoop
[hadoop@localhost hadoop]$ ./bin/hdfs dfs -rm /user/hadoop/merge.txt
Deleted /user/hadoop/merge.txt
现在,就可以在Linux系统中,使用hadoop jar命令运行程序,命令如下(注意是相对路径):
[hadoop@localhost hadoop]$ ./bin/hadoop jar ./myapp/HDFSExample.jar
结果如下: