文章目录
参考资料
视频资料
运行环境
- Windows10
- JDK8
- IDEA 2021.6 专业版
- Hadoop3.1.3
- CentOS7
- 3个Hadoop完全分布式集群节点
一、准备 HDFS Java API 环境
1.1 在windows系统中准备Hadoop环境
Hadoop3.1.3 官方下载地址:点击下载,下载后解压。
hadoop主要基于linux编写,这个winutil.exe主要用于模拟Linux系统下的目录环境。因此hadoop放在windows下运行的时候,需要这个辅助程序才能运行
这些环境软件下载到hadoop目录的bin文件夹:点击下载
之后在配置Hadoop的环境变量,跟Linux环境里一样,先配置HADOOP_HOME,再配置系统变量PATH
图形化操作可以右键此电脑,点击属性,然后点击高级系统设置,环境变量
配置好后,在cmd里查看版本
hadoop version
配置完毕.
1.2 使本机连接集群节点
1.2.1 域名映射
在本机配置域名映射,这样就可以直接通过主机名连接到对应的ID
windows10配置域名映射,位置在:
C:\WINDOWS\System32\drivers\etc\
hosts的配置内容:
如图:以 IP + 空格 + 主机名 的形式进行配置
IP的话如果是本机的虚拟机则可以在虚拟机里通过命令查看
ifconfig
显示的信息中,选择eth开头的信息,比如在Vmware里是eth33,而在docker容器里就是eth0
1.2.2 路由转发
由于笔者是在虚拟机里使用docker容器搭建的三个节点,那么则有:
- 虚拟机能和自身里的docker容器相连
- 本机能和虚拟机相连
若要本机直接和虚拟机里的docker容器相连,就要进行域名转发,可参考这篇博文:Docker | 使用宿主机ping通虚拟机里的docker容器 | 路由转发
配置完成后,可以直接在主机ping通集群节点,这样就可以在之后的本机程序里连接集群的HDFS了。
1.3 使用 IDEA 创建 Maven 项目
项目结构:
pom.xml
配置 Maven项目的依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.uni</groupId>
<artifactId>HDFSLearn</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.30</version>
</dependency>
</dependencies>
</project>
log4j.properties
配置 log4j日志文件的输出信息
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spring.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
至此,IDEA项目搭建完毕。
二、HDFS Java API 操作案例
2.1 创建文件夹
org.apache.hadoop.fs.FileSystem
源码中的相关方法:
public static boolean mkdirs(FileSystem fs, Path dir, FsPermission permission)
public abstract boolean mkdirs(Path f, FsPermission permission) throws IOException
public boolean mkdirs(Path f) throws IOException
参数说明:
参数 | 描述 |
---|---|
Path f | HDFS创建的文件目录 |
FsPermission permission | 当前用户的权限级别 |
测试代码:
public class HdfsClient {
private static Configuration configuration;
private static String HDFS_PATH = "hdfs://hadoop101:8020"; // HDFS 连接地址
private static String HDFS_USER = "root"; // HDFS 连接对象
private static FileSystem fs; // HDFS 文件操作对象
/* 单例模式 创建连接 **/
static { configuration = new Configuration(); }
public FileSystem getFileSystem(){
try{
if(fs == null)
fs = FileSystem.get(new URI(HDFS_PATH), configuration, HDFS_USER);
} catch (Exception e) {
e.printStackTrace();
}
return fs;
}
@Test
public void testMkdir() throws IOException{
FileSystem fs = getFileSystem();
fs.mkdirs(new Path("/uni/testMkdir/"));
fs.close();
}
}
2.2 上传文件
org.apache.hadoop.fs.FileSystem
源码中的相关方法:
public void copyFromLocalFile(Path src, Path dst)
public void moveFromLocalFile(Path[] srcs, Path dst)
public void copyFromLocalFile(boolean delSrc, Path src, Path dst)
public void copyFromLocalFile(boolean delSrc, boolean overwrite,Path[] srcs, Path dst)
public void copyFromLocalFile(boolean delSrc, boolean overwrite,Path src, Path dst)
参数说明:
参数 | 描述 |
---|---|
boolean delSrc | 是否删除HDFS路径所在的原数据 |
boolean overwrite | 是否允许覆盖原内容 |
Path src / []srcs | 本地数据路径 |
Path dst | HDFS目的地路径 |
测试代码:
@Test
public void testCopyFromLocalFile() throws IOException{
FileSystem fs = getFileSystem();
Path localFile = new Path("test.txt");
Path distPath = new Path("/uni/testMkdir");
fs.copyFromLocalFile(localFile, distPath);
fs.close();
}
2.3 下载文件
org.apache.hadoop.fs.FileSystem
源码中的相关方法:
public void copyToLocalFile(boolean delSrc, Path src, Path dst)
public void copyToLocalFile(boolean delSrc, Path src, Path dst,boolean useRawLocalFileSystem) throws IOException
public void copyToLocalFile(Path src, Path dst) throws IOException
参数说明:
参数 | 描述 |
---|---|
boolean delSrc | 是否删除本地路径所在的原数据 |
boolean overwrite | 是否允许覆盖原内容 |
Path src / []srcs | 本地数据路径 |
Path dst | HDFS目的地路径 |
boolean useRawLocalFileSystem | 是否开启本地文件校验(crc循环冗余校验) |
2.4 删除文件
org.apache.hadoop.fs.FileSystem
源码中的相关方法:
public boolean delete(Path f) throws IOException
public abstract boolean delete(Path f, boolean recursive) throws IOException
public boolean deleteOnExit(Path f) throws IOException
public void deleteSnapshot(Path path, String snapshotName)
参数说明:
参数 | 描述 |
---|---|
Path f | 要删除的路径地址 |
boolean recursive | 表示是否递归删除 |
Path dst | HDFS目的地路径 |
boolean useRawLocalFileSystem | 是否开启本地文件校验(crc循环冗余校验) |
测试代码:
@Test
public void testDelete(){
FileSystem fs = getFileSystem();
try{
fs.delete(new Path("/uni/testMkdir/test.txt"),true);
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
2.5 文件的更名和移动
org.apache.hadoop.fs.FileSystem
源码中的相关方法:
public abstract boolean rename(Path src, Path dst) throws IOException
测试方法:
@Test
public void testMove(){
FileSystem fs = getFileSystem();
try{
fs.rename(new Path("/uni/testMkdir"),new Path("/uni/MyDir"));
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
fs.close();
}
2.6 获取HDFS文件信息
org.apache.hadoop.fs.FileSystem
源码中的相关方法:
public RemoteIterator<LocatedFileStatus> listFiles(final Path f, final boolean recursive)
测试方法:
获取HDFS文件信息
@Test
public void testDetail() throws IOException {
FileSystem fs = getFileSystem();
// 获取所有文件信息
RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);
while (listFiles.hasNext()) {
LocatedFileStatus fileStatus = listFiles.next();
System.out.println("===========" + fileStatus.getPath() +"=========");
System.out.println(fileStatus.getPermission());
System.out.println(fileStatus.getOwner());
System.out.println(fileStatus.getGroup());
System.out.println(fileStatus.getLen());
System.out.println(fileStatus.getModificationTime());
System.out.println(fileStatus.getReplication());
System.out.println(fileStatus.getBlockSize());
System.out.println(fileStatus.getPath().getName());
}
fs.close();
}
获取HDFS文件的块信息:
@Test
public void testDetail() throws IOException {
FileSystem fs = getFileSystem();
// 获取所有文件信息
RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);
while (listFiles.hasNext()) {
LocatedFileStatus fileStatus = listFiles.next();
BlockLocation[] blockLocations = fileStatus.getBlockLocations();
System.out.println(Arrays.toString(blockLocations));
}
fs.close();
}
2.7 文件与文件夹的判断
@Test
public void testFile() throws IOException {
FileSystem fs = getFileSystem();
FileStatus[] listStatus = fs.listStatus(new Path("/"));
for (FileStatus status : listStatus) {
if(status.isFile())
System.out.println("文件:" + status.getPath().getName());
else
System.out.println("目录:" + status.getPath().getName());
}
fs.close();
}
2.8 HDFS - API 配置参数优先级问题
2.8.1 通过配置文件
hdfs-site.xml
可以将hadoop的配置文件 hdfs-site.xml
放到项目里的resources文件夹里,这样API在执行时会按照这个配置来执行。
2.8.2 通过Configuration对象
除了创建文件外,还可以通过配置Configuration
对象来设置参数
这个类是来自包 org.apache.hadoop.conf
的
范例: 将分区数设置成2
Configuration configuration = new Configuration();
configuration.set("dfs.replication", 2);
2.8.3 优先级问题
优先级从高到低依次为:
API程序的Configuration配置 > 项目资源文件下的配置文件 > 集群中 hdfs-site.xml
> 集群中hdfs-default.xml