本篇主要包括:HDFS概念、HDFS命令行操作、HDFS客户端操作,没有涉及到原理性知识,原理性知识将会在下一篇进行介绍。
HDFS概念
概念
HDFS,它是一个文件系统,用于存储文件,通过目录树来定位文件;其次,它是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色。
HDFS的设计适合一次写入,多次读出的场景,且不支持文件的修改。适合用来做数据分析,并不适合用来做网盘应用。
组成
NameNode
负责管理整个文件系统的元数据,以及每一个路径(文件)所对应的数据块信息。DataNode
负责管理用户的文件数据块,每一个数据块都可以在多个datanode上存储多个副本。Secondary NameNode
用来监控HDFS状态的辅助后台程序,每隔一段时间获取HDFS元数据的快照。
HDFS文件块大小
HDFS中的文件在物理上是分块存储(block),块的大小可以通过配置参数( dfs.blocksize)来规定,默认大小在hadoop2.x版本中是128M,老版本中是64M
HDFS命令行操作
-ls
: 显示目录信息hadoop fs -ls /
-mkdir
:在hdfs上创建目录hadoop fs -mkdir -p /aaa/bbb/cc/dd
-moveFromLocal
:从本地剪切粘贴到hdfshadoop fs - moveFromLocal /home/hadoop/a.txt /aaa/bbb/cc/dd
-appendToFile
:追加一个文件到已经存在的文件末尾hadoop fs -appendToFile a.txt /user/newDir/test.txt
-cat
:显示文件内容hadoop fs -cat /user/newDir/test.txt
-tail
:显示一个文件的末尾hadoop fs -tail /user/newDir/test.txt
-copyFromLocal
:从本地文件系统中拷贝文件到hdfs路径去hadoop fs -copyFromLocal ./jdk.tar.gz /aaa/
-copyToLocal
:从hdfs拷贝到本地hadoop fs -copyToLocal /aaa/jdk.tar.gz
-cp
:从hdfs的一个路径拷贝到hdfs的另一个路径hadoop fs -cp /aaa/jdk.tar.gz /bbb/jdk.tar.gz.2
-mv
:在hdfs目录中移动文件hadoop fs -mv /aaa/jdk.tar.gz /
-get
:等同于copyToLocal,就是从hdfs下载文件到本地hadoop fs -get /aaa/jdk.tar.gz
-getmerge
:合并下载多个文件,比如hdfs的目录 /aaa/下有多个文件:log.1, log.2,log.3,...hadoop fs -getmerge /aaa/log.* ./log.sum
-put
:等同于copyFromLocalhadoop fs -put /aaa/jdk.tar.gz /bbb/jdk.tar.gz.2
-rm
:删除文件或文件夹hadoop fs -rm -r /aaa/bbb/
-rmdir
:删除空目录hadoop fs -rmdir /aaa/bbb/ccc
-df
:统计文件系统的可用空间信息hadoop fs -df -h /
-du
:统计文件夹的大小信息hadoop fs -du -s -h /aaa/*
-count
:统计一个指定目录下的文件节点数量hadoop fs -count /aaa/
-setrep
:设置hdfs中文件的副本数量hadoop fs -setrep 3 /aaa/jdk.tar.gz
HDFS客户端操作
添加依赖
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-client -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-common -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.2</version>
</dependency>
通过API操作HDFS
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import java.net.URI;
/**
* @author sixiaojie
* @date 2019-11-13 13:38
*/
public class HDFSClientDemo {
public static void main(String[] args) throws Exception{
//创建配置信息对象
Configuration configuration = new Configuration();
//获取文件系统
FileSystem fs = FileSystem.get(new URI("hdfs://192.168.48.111:9000"),configuration,"root");
//操作文件系统
//上传本地数据到集群
fs.copyFromLocalFile(new Path("E:\\test.png"),new Path("/user/sixj/test2.png"));
//下载
fs.copyToLocalFile(false,new Path("/user/sixj/test2.png"),new Path("E:\\test2.png"),true);
//创建目录
fs.mkdirs(new Path("/user/sixj/client"));
//重命名文件或目录
fs.rename(new Path("/user/sixj/test2.png"),new Path("/user/sixj/testRename.png"));
//删除目录,如果是非空目录,参数2必须为true
fs.delete(new Path("/user/sixj/test1.png"),true);
//查看文件详情
readFileAtHdfs(fs);
//查看文件夹
findAtHdfs(fs);
//关闭fs
fs.close();
}
/**
* 查看文件详情
* @param fs
* @throws Exception
*/
static void readFileAtHdfs(FileSystem fs) throws Exception{
RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/user/sixj"), true);
while (listFiles.hasNext()){
LocatedFileStatus status = listFiles.next();
// 文件名称
System.out.println(status.getPath().getName());
// 文件内容长度
System.out.println(status.getLen());
// 文件权限
System.out.println(status.getPermission());
//文件块的具体信息
BlockLocation[] blockLocations = status.getBlockLocations();
for (BlockLocation block : blockLocations) {
System.out.println(block.getOffset());
String[] hosts = block.getHosts();
for (String host : hosts) {
System.out.println(host);
}
}
}
}
/**
* 获取查询路径下的文件状态信息
* @param fs
* @throws Exception
*/
static void findAtHdfs(FileSystem fs) throws Exception {
FileStatus[] listStatus = fs.listStatus(new Path("/user/sixj"));
// 遍历所有文件状态
for (FileStatus status : listStatus) {
if (status.isFile()) {
System.out.println("f--" + status.getPath().getName());
} else {
System.out.println("d--" + status.getPath().getName());
}
}
}
}
如果在开发过程中出现这个异常:java.io.IOException: HADOOP_HOME or hadoop.home.dir are not set
需要解压hadoop程序包到本地非中文目录,同时在你的环境变量中的系统变量中配置了HADOOP_HOME并且指向hadoop程序包的本目录即可,并且在系统变量的path中附加了%HADOOP_HOME%/bin(这里一定要指向到bin这一级才行),然后一定要重启电脑才行。
hadoop程序包下载地址:
win10:pan.baidu.com/s/1PYEyGRBb…
win7:pan.baidu.com/s/1up3G8lra…
通过IO流操作HDFS
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;
import java.io.*;
import java.net.URI;
/**
* @author sixiaojie
* @date 2019-11-13 17:30
*/
public class IOToHDFS {
/**
* 文件上传
* 客户端通过输入流读取磁盘上文件,通过输出流上传到文件系统
* @throws Exception
*/
static void putFileToHDFS() throws Exception{
//创建配置信息对象
Configuration configuration = new Configuration();
//获取文件系统
FileSystem fs = FileSystem.get(new URI("hdfs://192.168.48.111:9000"),configuration,"root");
//获取输出流
FSDataOutputStream fos = fs.create(new Path("/user/sixj/hadoop-2.7.2.rar"));
//获取输入流
FileInputStream fis = new FileInputStream(new File("E:\\hadoop-2.7.2.rar"));
try{
//流对接
IOUtils.copyBytes(fis,fos,4096,false);
}catch (Exception e){
e.printStackTrace();
}finally {
IOUtils.closeStream(fis);
IOUtils.closeStream(fos);
}
//关闭fs
fs.close();
}
/**
* 文件下载
* @throws Exception
*/
static void getFileFromHDFS() throws Exception{
//创建配置信息对象
Configuration configuration = new Configuration();
//获取文件系统
FileSystem fs = FileSystem.get(new URI("hdfs://192.168.48.111:9000"),configuration,"root");
//获取输入流
FSDataInputStream fis = fs.open(new Path("/user/sixj/test.png"));
//创建输出流
FileOutputStream fos = new FileOutputStream(new File("E:\\download.png"));
try{
//流对接
IOUtils.copyBytes(fis,fos,4096,false);
}catch (Exception e){
e.printStackTrace();
}finally {
IOUtils.closeStream(fis);
IOUtils.closeStream(fos);
}
//关闭fs
fs.close();
}
/**
* 下载大文件的第一块数据
*/
static void getFileFromHDFSSeek1() throws Exception{
//创建配置信息对象
Configuration configuration = new Configuration();
//获取文件系统
FileSystem fs = FileSystem.get(new URI("hdfs://192.168.48.111:9000"),configuration,"root");
//获取输入流
FSDataInputStream fis = fs.open(new Path("/user/sixj/hadoop-2.7.2.rar"));
//创建输出流
FileOutputStream fos = new FileOutputStream(new File("E:\\hadoop-2.7.2.rar.part1"));
try{
byte[] buf = new byte[1024];
for (int i = 0; i < 128 * 1024; i++) {
fis.read(buf);
fos.write(buf);
}
}catch (Exception e){
e.printStackTrace();
}finally {
IOUtils.closeStream(fis);
IOUtils.closeStream(fos);
}
//关闭fs
fs.close();
}
/**
* 下载大文件的第一块数据
*/
static void getFileFromHDFSSeek2() throws Exception{
//创建配置信息对象
Configuration configuration = new Configuration();
//获取文件系统
FileSystem fs = FileSystem.get(new URI("hdfs://192.168.48.111:9000"),configuration,"root");
//获取输入流
FSDataInputStream fis = fs.open(new Path("/user/sixj/hadoop-2.7.2.rar"));
//创建输出流
FileOutputStream fos = new FileOutputStream(new File("E:\\hadoop-2.7.2.rar.part2"));
try{
byte[] buf = new byte[1024];
for (int i = 128 * 1024; i < 2 * 128 * 1024; i++) {
fis.read(buf);
fos.write(buf);
}
}catch (Exception e){
e.printStackTrace();
}finally {
IOUtils.closeStream(fis);
IOUtils.closeStream(fos);
}
//关闭fs
fs.close();
}
public static void main(String[] args) throws Exception{
// putFileToHDFS();
// getFileFromHDFS();
// getFileFromHDFSSeek1();
getFileFromHDFSSeek2();
}
}