文章目录
前言
一、HDFS的概述
【1】HDFS产生背景
【2】HDFS的定义
【3】HDFS的优缺点
【4】HDFS结构
【5】HDFS的文件块大小
二、HDFS的shell操作
1、上传
2、下载
3、HDFS直接操作
三、HDFS的API操作
3.1? 客户端环境准备
3.2? HDFS的API案例实操
总结
前言
hadoop笔记第五篇——HDFS的概述和HDFS的shell操作。在前面我们已经将完全分布式集群搭建完成,接下来就是HDFS了
一、HDFS的概述
【1】HDFS产生背景
????????随着数据量越来越大,在一个操作系统存不下所有的数据,那么就分配到更多的操作系统管理的磁盘中,但是不方便管理和维护,迫切需要一种系统来管理多台机器上的文件,这就是分布式文件管理系统。HDFS 只是分布式文件管理系统中的一种
【2】HDFS的定义
????????HDFS(Hadoop Distributed File System),它是一个文件系统,用于存储文件,通过目录树来定位文件;其次,它是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色。HDFS 的使用场景:适合一次写入,多次读出的场景。一个文件经过创建、写入和关闭之后就不需要改变
【3】HDFS的优缺点
优点:
1、高容错性:
2、适合处理大数据
3、可构建在廉价机器上,通过多副本机制,提高可靠性
缺点:
1、不适合低延时数据访问,比如毫秒级的存储数据,是做不到的。
2、无法高效的对大量小文件进行存储。
3、不支持并发写入、文件随机修改。
【4】HDFS结构
【5】HDFS的文件块大小
????????HDFS的文件在物理上是分块存储(block),块的大小可以通过配置参数(dfs.blocksize)来修改,默认大小Hadoop2.x/hadoop3.x版本是128M,1.x版本是64M
思考:为什么块的大小不能设置太小,也不能设置太大?
(1)HDFS的块设置太小,会增加寻址时间,程序一直在找块的开始位置; (2)如果块设置的太大,从磁盘传输数据的时间会明显大于定位这个块开始位置所需的时间。导致程序在处理这块数据时,会非常慢。
总结:HDFS块的大小设置主要取决于磁盘传输速率。
二、HDFS的shell操作
基本语法
? ? ? ? hadoop fs 具体命令?
? ? ? ? hdfs dfs? 具体命令
两个作用一样
1、上传
【1】-moveFromLocal 从本地剪切到hdfs
?【2】-copyFromLocal:从本地文件系统拷贝文件到HDFS路径去
【3】 -put 等同于copyFromLocal 生产环境更习惯用put
hadoop fs -put libai3.txt /Atest
【4】-appendToFile 追加一个文件到已经存在的文件末尾
2、下载
【1】-copyTolocal 从hdfs拷贝到本地
将libai.txt文件下载回来
【2】-get 等同于上一个 一般习惯用get
3、HDFS直接操作
【1】-ls显示目录信息
【2】-cat:显示文件内容
? ? ? ? hadoop fs -cat /Atest/libai1.txt
【3】-chgrp、-chmod、chown:修改文件所属权限
【4】-mkdir 创建路径
? ? ? ? ?hadoop fs -mkdir /tangshi
【5】-cp:从 HDFS 的一个路径拷贝到 HDFS 的另一个路径
????????
【6】-mv 在HDFS目录中移动文件
? ? ? ?
?【7】-tail显示一个文件末尾1kb的数据
【8】-rm 删除文件或文件夹
????????hadoop fs -rm /Atest/libai.txt
【9】-rm -r 递归删除文件夹
????????hadoop fs -rm -r /sanguo
【10】-du 统计文件夹的大小信息
【11】-setrep 设置HDFS中文件的副本数量
?????????hadoop fs -setrep 10 /tansghi/libai.txt
????????这里设置的副本数只是记录在 NameNode 的元数据中,是否真的会有这么多副本,还得看 DataNode 的数量。因为目前只有 3 台设备,最多也就 3 个副本,只有节点数的增加到 7台时,副本数才能达到 7
三、HDFS的API操作
3.1? 客户端环境准备
【1】将win10下编译过的hadoop拷贝到自定义盘符及路径
【2】配置windows环境变量
?【3】在idea创建maven工程 ,导入响应的依赖坐标
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs-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>
【4】在在项目的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
?【5】开始写代码
public class HdfsClient {
@Test
public void testmkdir() throws URISyntaxException, IOException, InterruptedException {
//连接的集群地址
URI uri = new URI("hdfs://hadoop02:8020");
//用户
String user = "zhou";
//创建一个配置文件
Configuration configuration = new Configuration();
//获取客户端对象
FileSystem fs = FileSystem.get(uri, configuration,user);
//创建一个文件夹
fs.mkdirs(new Path("/xiyou/huaguoshan"));
//关闭资源
fs.close();
}
}
【6】执行程序
客户端去操作 HDFS 时,是有一个用户身份的。默认情况下,HDFS 客户端 API 会从采 用 Windows 默认用户访问 HDFS,会报权限异常错误。所以在访问 HDFS 时,一定要配置用户
3.2? HDFS的API案例实操
?前提 初始化获取连接对象(before) 关闭资源 (after)
private FileSystem fs;
@Before
public void init() throws URISyntaxException, IOException, InterruptedException {
//连接集群
URI uri = new URI("hdfs://hadoop02:8020");
//创建配置文件
Configuration configuration = new Configuration();
//创建用户
String user = "zhou";
//获取客户端对象
fs = FileSystem.get(uri, configuration, user);
}
//关闭资源
@After
public void close() throws IOException {
fs.close();
}
【1】HDFS文件上传
//文件上传
@Test
public void testPut() throws IOException {
// 参数解读:参数一:表示删除原数据; 参数二:是否允许覆盖;参数三:原数据路径; 参数四:目的地路径
fs.copyFromLocalFile(true, true, new Path("D:\\dufu2.txt"), new Path("/tangshi/jueju"));
}
【2】HDFS文件下载
//文件下载
@Test
public void testGet() throws IOException {
//参数解读:参数一:源文件是否删除 参数二:原文件的路径hdfs路径 参数三:目标地址路径:windows 参数四:
fs.copyToLocalFile(false, new Path("hdfs://hadoop02/wangjiawei.txt"), new Path("D:\\"), true);
}
【3】文件删除
//删除
@Test
public void testRm() throws IOException {
//参数解读 :参数一:要删除的路径 参数二:是否递归删除
//删除文件
fs.delete(new Path("/tangshi/libai3.txt"), false);
//删除空目录
fs.delete(new Path("/xiyou/huaguoshan1"), false);
//删除非空目录
fs.delete(new Path("/tangshi"), true);
}
【4】文件的更名与移动
//文件的更名和移动
@Test
public void testMv() throws IOException {
//参数一:原文件路径 参数二:目标文件路径
//对文件名称修改
// fs.rename(new Path("/sanguo/wuguo.txt"),new Path("/sanguo/caocao.txt"));//将/sanguo/wuguo.txt改成caocao.txt
//文件的移动和更名将/sanguo/shuguo2.txt移动到/目录下并修改名字为liubei.txt
// fs.rename(new Path("/sanguo/shuguo2.txt"),new Path("/liubei.txt"));
//目录更名 将/wcinput改为/wcoutput
fs.rename(new Path("/wcinput"), new Path("/wcoutput"));
【5】获取文件详细信息
//获取文件详细信息
@Test
public void testFileDetil() throws IOException {
//获取所有文件信息
//参数解读:参数一:文件路径 参数二:是否遍历
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());//块大小
fileStatus.getPath().getName();
//获取块信息
BlockLocation[] blockLocations = fileStatus.getBlockLocations();
System.out.println(Arrays.toString(blockLocations));
}
}
?【6】HDFS文件判断
//hdfs文件和文件夹的判断
@Test
public void testFile() throws IOException {
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());
}
}
}
总结
【1】hdfs的优缺点?
【2】文件块大小 决定文件块大小的因素是什么
【3】HDFS体系结构
【4】常用的shell操作
【5】HDFS的API操作
|