HDFS
- 第 1 章 HDFS 概述
- 1.1 HDFS 产出背景及定义
- 1.2 HDFS 优缺点
- 1.3 HDFS 组成架构
- 1.4 HDFS 文件块大小(面试重点)
- 第 2 章 HDFS 的 Shell 操作(开发重点)
- 2.1 基本语法
- 2.2 命令大全
- 2.3 常用命令实操
- 第 3 章 HDFS 的 API 操作
- 3.1 客户端环境准备
- 3.2 HDFS 的 API 案例实操
- 3.2.0 HDFS 创建文件夹( fs.mkdirs( new Path() ) )
- 3.2.1 HDFS 文件上传(fs.copyFromLocalFile())
- 3.2.2 HDFS 文件下载(fs.copyToLocalFile())
- 3.2.3 HDFS 文件更名和移动(rename( new Path(),new Path() ) )
- 3.2.4 HDFS 删除文件和目录(delete(new Path(""),bollean))
- 3.2.5 HDFS 文件详情查看
- 3.2.6 HDFS 文件和文件夹判断
- 第 4 章 HDFS 的读写流程(面试重点)
- 4.1 HDFS 写数据流程
- 4.1.1 剖析文件写入
- 4.1.2 网络拓扑-节点距离计算
- 4.1.3 机架感知(副本存储节点选择)
- 4.2 HDFS 读数据流程
- 第 5 章 NameNode 和 SecondaryNameNode
- 5.1 NN 和 2NN 工作机制
- 5.2 Fsimage 和 Edits 解析
- 第 6 章 DataNode
- 6.1 DataNode 工作机制
- 6.2 数据完整性
- 6.3 掉线时限参数设置
- 总结
第 1 章 HDFS 概述
1.1 HDFS 产出背景及定义
- 需要一种系统来管理多台机器上的文件,这就是分布式文件管理系统。HDFS 只是分布式文件管理系统中的一种
- HDFS 的使用场景:适合一次写入,多次读出的场景。一个文件经过创建、写入和关闭之后就不需要改变
1.2 HDFS 优缺点
优点
- 高容错性
- 适合处理大数据
- 可构建在廉价机器上,通过多副本机制,提高可靠性
缺点
- 不适合低延时数据访问
- 无法高效的对大量小文件进行存储
- 不支持并发写入、文件随机修改
1.3 HDFS 组成架构
1.4 HDFS 文件块大小(面试重点)
第 2 章 HDFS 的 Shell 操作(开发重点)
2.1 基本语法
hadoop fs 具体命令 OR hdfs dfs 具体命令
2.2 命令大全
[atguigu@hadoop102 hadoop-3.1.3]$ bin/hadoop fs
2.3 常用命令实操
2.3.1 操作命令
序号 | 命令 | 意义 |
1 | hdfs dfs -mkdir [-p] 路径 | 创建文件夹(-p:联级创建) |
2 | hdfs dfs -ls [-d] [-h] [-R] 路径 | 列出指定的文件和目录 |
3 | hdfs dfs -touchz 路径 | 新建文件 |
4 | hdfs dfs -put [-f] [-p] 本地文件路径 保存在HDFS路径 | 上传文件 |
5 | hdfs dfs -moveFromLocal 本地文件路径 保存在HDFS路径 | 将本地移动到 HDFS |
6 | hdfs dfs cat 查看路径 | 查看文件 |
7 | hdfs dfs appendToFile 本地文件内容 目标文件夹 | 追写文件(注:本地文件内容处是“-”时,表示数据来自键盘输入) |
8 | hdfs dfs -get [-p] HDFS中的完整路径 保存地 | 下载文件 |
9 | hdfs dfs -rm [-f] [-r/R] 路径 | 删除目录或文件(-f,删除的文件不报错;-r或-R,联级删除) |
2.3.2 HDFS 直接操作
- -ls: 显示目录信息
- -cat:显示文件内容
- -chgrp、-chmod、-chown:Linux 文件系统中的用法一样,修改文件所属权限
- -mkdir:创建路径
- -cp:从 HDFS 的一个路径拷贝到 HDFS 的另一个路径
- -mv:在 HDFS 目录中移动文件
- -tail:显示一个文件的末尾 1kb 的数据
- -rm:删除文件或文件夹
- -rm -r:递归删除目录及目录里面内容
- -du 统计文件夹的大小信息
- -setrep:设置 HDFS 中文件的副本数量
第 3 章 HDFS 的 API 操作
3.1 客户端环境准备
- 1:找到资料包路径下的 Windows 依赖文件夹,拷贝 hadoop-3.1.0 到非中文路径(比如 d:\)
- 2:配置 HADOOP_HOME 环境变量
- 3:配置 Path 环境变量
- 4:在 IDEA 中创建一个 Maven 工程 HdfsClientDemo,并导入相应的依赖坐标+日志添加
<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>
- 5:在项目的 src/main/resources 目录下,新建一个文件,命名为“log4j.properties”,在文件中填入
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
- 6:创建包名:com.atguigu.hdfs
- 7:创建 HdfsClient 类
- 8:执行程序
3.2 HDFS 的 API 案例实操
package com.atguigu.hdfs;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
/**
* @author shkstart
* @create 2021-03-19 20:23
*/
public class HdfsClient {
private FileSystem fs;
@Before
public void init() throws URISyntaxException, IOException, InterruptedException {
//连接集群的地址
URI uri = new URI("hdfs://hadoop102:8020");
//创建一个配置文件
Configuration configuration = new Configuration();
//用户
String user = "atguigu";
//1 获取客户端对象
fs = FileSystem.get(uri,configuration,user);
}
@After
public void close() throws IOException {
//3.关闭资源
fs.close();
}
//创建一个文件夹
@Test
public void testMkdirs() throws IOException, URISyntaxException, InterruptedException {
//2 创建一个文件夹
fs.mkdirs(new Path("/xiyou/huaguoshan1"));
}
//上传文件
@Test
//参数解读;参数一:表示是否删除原数据,参数二;是否允许覆盖,参数三:原数据路径,参数四:目的的路径
public void testPut() throws IOException {
fs.copyFromLocalFile(false,false,new Path("D:\\sunwukong.txt"),
new Path("hdfs://hadoop102/xiyou/huaguoshan1/sunwukong.txt"));
}
//下载文件
@Test
public void testdowload() throws IOException {
fs.copyToLocalFile(false,new Path("hdfs://hadoop102/xiyou/huaguoshan1/sunwukong.txt"),
new Path("D:\\sunwukong2.txt"),true);
}
//文件更名
@Test
public void testRename() throws IOException {
fs.rename(new Path("/xiyou/huaguoshan1/sunwukong.txt"),
new Path("/xiyou/huaguoshan1/meihouwang.txt"));
}
//删除文件和目录
@Test
public void testDelete() throws IOException {
fs.delete(new Path("/xiyou"),true);
}
}
注意:新建一个Java测试hdfs类
自己的安装位置
D:\ProgramFiles\java\Workspace_idea\test\hadoop\HDFSClient
注意:创建一个配置文件,所需导入的包
Configuration configuration = new Configuration();
注意:Before、test、afterd的应用
3.2.0 HDFS 创建文件夹( fs.mkdirs( new Path() ) )
注意://创建一个文件夹,所需导入的包
fs.mkdirs(new Path("/xiyou/huaguoshan1"));
创建文件夹成功图
3.2.1 HDFS 文件上传(fs.copyFromLocalFile())
上传文件:copyFromLocalFile()方法,所需选择的参数
注意:上传的路径不可以已经存在,否则会报错
上传成功效果图
3.2.2 HDFS 文件下载(fs.copyToLocalFile())
copyToLocalFile()方法参数:
- boolean delSrc 指是否将原文件删除
- Path src 指要下载的文件路径
- Path dst 指将文件下载到的路径
- boolean useRawLocalFileSystem 是否开启文件校验(如:false,会同时生成一个CRC校验文件)
下载成功效果图
3.2.3 HDFS 文件更名和移动(rename( new Path(),new Path() ) )
3.2.4 HDFS 删除文件和目录(delete(new Path(""),bollean))
3.2.5 HDFS 文件详情查看
3.2.6 HDFS 文件和文件夹判断
第 4 章 HDFS 的读写流程(面试重点)
4.1 HDFS 写数据流程
4.1.1 剖析文件写入
- (1)客户端通过 Distributed FileSystem 模块向 NameNode 请求上传文件,NameNode 检查目标文件是否已存在,父目录是否存在
- (2)NameNode 返回是否可以上传。
- (3)客户端请求第一个 Block 上传到哪几个 DataNode 服务器上。
- (4)NameNode 返回 3 个 DataNode 节点,分别为 dn1、dn2、dn3。
- (5)客户端通过 FSDataOutputStream 模块请求 dn1 上传数据,dn1 收到请求会继续调用dn2,然后 dn2 调用 dn3,将这个通信管道建立完成。
- (6)dn1、dn2、dn3 逐级应答客户端。
- (7)客户端开始往 dn1 上传第一个 Block(先从磁盘读取数据放到一个本地内存缓存),以 Packet 为单位,dn1收到一个 Packet 就会传给 dn2,dn2 传给 dn3;dn1 每传一个 packet会放入一个应答队列等待应答。
- (8)当一个 Block 传输完成之后,客户端再次请求 NameNode 上传第二个 Block 的服务器。(重复执行 3-7 步)。
4.1.2 网络拓扑-节点距离计算
略
4.1.3 机架感知(副本存储节点选择)
Hadoop3.1.3 副本节点选择
4.2 HDFS 读数据流程
- (1)客户端通过 DistributedFileSystem 向 NameNode 请求下载文件,NameNode 通过查询元数据,找到文件块所在的 DataNode 地址。
- (2)挑选一台 DataNode(就近原则,然后随机)服务器,请求读取数据。
- (3)DataNode 开始传输数据给客户端(从磁盘里面读取数据输入流,以 Packet 为单位来做校验)。
- (4)客户端以 Packet 为单位接收,先在本地缓存,然后写入目标文件。
第 5 章 NameNode 和 SecondaryNameNode
5.1 NN 和 2NN 工作机制
- NameNode 中的元数据是存储在FsImage
- 引入 Edits 文件(只进行追加操作,效率很高)。每当元数据有更新或者添加元数据时,修改内存中的元数据并追加到 Edits 中
- SecondaryNamenode定期进行 FsImage 和 Edits 的合并
1)第一阶段:NameNode 启动
- (1)第一次启动 NameNode 格式化后,创建 Fsimage 和 Edits 文件。如果不是第一次启动,直接加载编辑日志和镜像文件到内存。
- (2)客户端对元数据进行增删改的请求。
- (3)NameNode 记录操作日志,更新滚动日志。 - (4)NameNode 在内存中对元数据进行增删改。
2)第二阶段:Secondary NameNode 工作
- (1)Secondary NameNode 询问 NameNode 是否需要 CheckPoint。直接带回 NameNode
是否检查结果。 - (2)Secondary NameNode 请求执行 CheckPoint。
- (3)NameNode 滚动正在写的 Edits 日志。
- (4)将滚动前的编辑日志和镜像文件拷贝到 Secondary NameNode。
- (5)Secondary NameNode 加载编辑日志和镜像文件到内存,并合并。
- (6)生成新的镜像文件 fsimage.chkpoint。
- (7)拷贝 fsimage.chkpoint 到 NameNode。
- (8)NameNode 将 fsimage.chkpoint 重新命名成 fsimage。
5.2 Fsimage 和 Edits 解析
NameNode被格式化之后,将在==/opt/module/hadoop-3.1.3/data/dfs/name/current==目录中产生如下文件
每次NameNode启动的时候都会将Fsimage文件读入内存,加载Edits里面的更新操作,保证内存中的元数据信息是最新的、同步的,可以看成NameNode启动的时候就将Fsimage和Edits文件进行了合并。
oiv 查看 Fsimage 文件,oev 查看 Edits 文件
hdfs oiv -p 文件类型 -i 镜像文件 -o 转换后文件输出路径
hdfs oev -p 文件类型 -i 编辑日志 -o 转换后文件输出路径
第 6 章 DataNode
6.1 DataNode 工作机制
- (1)一个数据块在 DataNode 上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳。
- (2)DataNode 启动后向 NameNode 注册,通过后,周期性(6 小时)的向 NameNode 上报所有的块信息。
- (3)心跳是每 3 秒一次,心跳返回结果带有 NameNode 给该 DataNode 的命令如复制块数据到另一台机器,或删除某个数据块。如果超过 10 分钟没有收到某个 DataNode 的心跳,则认为该节点不可用。
- (4)集群运行中可以安全加入和退出一些机器。
6.2 数据完整性
底层采用CRC校验
6.3 掉线时限参数设置
总结
- 1、HDFS文件块大小(面试重点)
硬盘读写速度
在企业中 一般128m(中小公司) 256m (大公司) - 2、HDFS的Shell操作(开发重点)
- 3、HDFS的读写流程(面试重点)