产生背景
需要一种系统来管理多台机器上的文件 → 分布式文件管理系统。
HDFS : 一种分布式文件管理系统
HDFS定义
HDFS(Hadoop Distributed File System),一个文件系统,用于存储文件,通过目录树来定位文件;分布式,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色。
使用场景:适合一次写入、多次读出的场景
NameNode(nn):Master,主管、管理者
DataNode:Slava。NameNode下达命令,DataNode执行实际的操作
Client:客户端
Secondary NameNode:并非NameNode的热备,当NN挂掉,它并不能马上替换NN并提供服务。
HDFS中的文件在物理上是分块(Block)存储,块的大小可以通过配置参数(dfs.blocksize)来规定。
默认大小:Hadoop1.x版本中64M,2.x和3.x版本中是128M
【HDFS块的大小设置主要取决于磁盘传输速率】
→ 太小:增加寻址时间。
→ 太大:从磁盘传输数据的时间会明显大于定位这个块开始位置所需的时间。
hadoop fs 具体命令 OR hdfs dfs 具体命令【完全相同】

启动Hadoop集群

-help
查看创建命令
创建/sanguo文件夹


-copyFromLocal:从本地文件系统中拷贝文件到 HDFS 路径去

-put:等同于 copyFromLocal,生产环境更习惯用 put
-appendToFile:追加一个文件到已经存在的文件末尾

-ls: 显示目录信息
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop fs -ls /sanguo
-cat:显示文件内容
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop fs -cat /sanguo/shuguo.txt
-chgrp、-chmod、-chown:Linux 文件系统中的用法一样,修改文件所属权限
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop fs -chmod 666
/sanguo/shuguo.txt
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop fs -chown atguigu:atguigu /sanguo/shuguo.txt
-mkdir:创建路径
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop fs -mkdir /jinguo
-cp:从 HDFS 的一个路径拷贝到 HDFS 的另一个路径
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop fs -cp /sanguo/shuguo.txt
/jinguo
-mv:在 HDFS 目录中移动文件
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop fs -mv /sanguo/wuguo.txt /jinguo
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop fs -mv /sanguo/weiguo.txt
/jinguo
-tail:显示一个文件的末尾 1kb 的数据
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop fs -tail /jinguo/shuguo.txt
-rm:删除文件或文件夹
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop fs -rm /sanguo/shuguo.txt
-rm -r:递归删除目录及目录里面内容
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop fs -rm -r /sanguo
-du 统计文件夹的大小信息
27 表示文件大小;81 表示 27*3 个副本;/jinguo 表示查看的目录
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop fs -du -s -h /jinguo
27 81 /jinguo
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop fs -du -h /jinguo
14 42 /jinguo/shuguo.txt
7 21 /jinguo/weiguo.txt
6 18 /jinguo/wuguo.tx
-setrep:设置 HDFS 中文件的副本数量
[atguigu@hadoop102 hadoop-3.1.3]$ hadoop fs -setrep 10 /jinguo/shuguo.txt
这里设置的副本数只是记录在 NameNode 的元数据中,是否真的会有这么多副本,还得看 DataNode 的数量。因为目前只有 3 台设备,最多也就 3 个副本,只有节点数的增加到 10台时,副本数才能达到 10。
配置HADOOP_HOME环境变量
配置Path环境变量
在 IDEA 中创建一个 Maven 工程 HdfsClientDemo,并导入相应的依赖坐标+日志添加
org.apache.hadoop
hadoop-client
3.1.3
junit
junit
4.12
org.slf4j
slf4j-log4j12
1.7.30
代码
public class HdfsClient {
@Test
public void testMkdirs() throws IOException,URISyntaxException,InterruptedException{
// 1. 获取文件系统
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"),configuration,"atguigu");
//2. 创建目录
fs.mkdirs(new Path("/xiyou/huaguoshan/"));
// 3. 关闭资源
fs.close();
}
}
执行程序

创建成功
@Test
public void testCopyFromLocalFile() throws IOException,InterruptedException,URISyntaxException{
//1. 获取文件系统
Configuration configuration = new Configuration();
configuration.set("dfs.replication","2");
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"),configuration,"atguigu");
//2.上传文件
fs.copyFromLocalFile(new Path("d:/sunwukong.txt"),new Path("/xiyou/huaguoshan"));
//3.关闭资源
fs.close();
}

【参数优先级】
客户端代码中设置的值 > ClassPath下用户自定义配置文件 > 服务器的自定义配置(xxx-site.xml) > 服务器的默认配置(xxx-default.xml)
@Test
public void testCopyToLocalFile() throws IOException,
InterruptedException, URISyntaxException{
// 1 获取文件系统
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"),
configuration, "atguigu");
// 2 执行下载操作
// boolean delSrc 指是否将原文件删除
// Path src 指要下载的文件路径
// Path dst 指将文件下载到的路径
// boolean useRawLocalFileSystem 是否开启文件校验
fs.copyToLocalFile(false, new
Path("/xiyou/huaguoshan/sunwukong.txt"), new Path("d:/sunwukong2.txt"),
true);
// 3 关闭资源
fs.close();
}

@Test
public void testRename() throws IOException, InterruptedException,
URISyntaxException{
// 1 获取文件系统
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"),
configuration, "atguigu");
// 2 修改文件名称
fs.rename(new Path("/xiyou/huaguoshan/sunwukong.txt"), new
Path("/xiyou/huaguoshan/meihouwang.txt"));
// 3 关闭资源
fs.close();
}
@Test
public void testDelete() throws IOException, InterruptedException,
URISyntaxException{
// 1 获取文件系统
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"),
configuration, "atguigu");
// 2 执行删除
fs.delete(new Path("/xiyou"), true);
// 3 关闭资源
fs.close();
}
@Test
public void testListFiles() throws IOException, InterruptedException,
URISyntaxException {
// 1 获取文件系统
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"),
configuration, "atguigu");
// 2 获取文件详情
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());
// 获取块信息
BlockLocation[] blockLocations = fileStatus.getBlockLocations();
System.out.println(Arrays.toString(blockLocations));
}
// 3 关闭资源
fs.close();
}
@Test
public void testListStatus() throws IOException, InterruptedException,
URISyntaxException{
// 1 获取文件配置信息
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:8020"),
configuration, "atguigu");
// 2 判断是文件还是文件夹
FileStatus[] listStatus = fs.listStatus(new Path("/"));
for (FileStatus fileStatus : listStatus) {
// 如果是文件
if (fileStatus.isFile()) {
System.out.println("f:"+fileStatus.getPath().getName());
}else {
System.out.println("d:"+fileStatus.getPath().getName());
}
}
// 3 关闭资源
fs.close();
}
在 HDFS 写数据的过程中,NameNode 会选择距离待上传数据最近距离的 DataNode 接收数据。
节点距离:两个节点到达最近的共同祖先的距离总和。

FsImage:在磁盘中备份元数据。
Edits文件(只进行追加操作,效率高):每当有元数据更新或者添加元数据时,修改内存中的元数据并追加到Edits中。【当NN节点断电,F + E → 元数据】
SecondaryNamenode:专门用于FsImage和Edits的合并。
【NN工作机制】
NN被格式化后,将在/opt/module/hadoop-3.1.3/data/tmp/dfs/name/current目录中产生如下文件

oiv查看Fsimage文件
hdfs oiv -p 文件类型 -i 镜像文件 -o 转换后文件输出路径
oev 查看 Edits 文件
hdfs oev -p 文件类型 -i 编辑日志 -o 转换后文件输出路径
通常情况下,SecondaryNameNode 每隔一小时执行一次。
[hdfs-default.xml]
dfs.namenode.checkpoint.period
3600s
一分钟检查一次操作次数,当操作次数达到 1 百万时,SecondaryNameNode 执行一次。
dfs.namenode.checkpoint.txns
1000000
操作动作次数
dfs.namenode.checkpoint.check.period
60s
1分钟检查一次操作次数
DN节点保证数据完整性的方法:
DataNode进程死亡或者网络故障造成DataNode无法与NameNode通信
NameNode不会立即把该节点判定为死亡,要经过一段时间,这段时间暂称作超时时长。
HDFS默认的超时时长为10分钟+30秒。
如果定义超时时间为TimeOut,则超时时长的计算公式为:
TimeOut = 2 * dfs.namenode.heartbeat.recheck-interval + 10 * dfs.heartbeat.interval。
而默认的dfs.namenode.heartbeat.recheck-interval 大小为5分钟,dfs.heartbeat.interval默认为3秒。
保证数据完整性的方法:
【注意】hdfs-site.xml 配置文件中的 heartbeat.recheck.interval 的单位为毫秒,dfs.heartbeat.interval 的单位为秒。