一、HDFS概述
HDFS的定义
HDFS的特点:
优点:
①高容错
②适合处理大数据
③可运行在廉价的机器上。
缺点:
①不适合低延时的数据处理
②无法高效的对小文件进行存储
③不支持并发的写入,文件的随机修改
HDFS的组成
HDFS 的文件块大小:
HDFS中文件在物理上是分块存储的,块的大小可以灵活配置。Hadoop3中默认是128M。
二、HDFS的常用Shell命令
基本语法:hadoop fs 具体命令 或 hdfs dfs 具体命令——两者作用相同。
①启动集群:start-dfs.sh//在namenode节点启动
②查看帮助:-help
③显式目录信息:-ls
④创建目录:-mkdir
⑤从本地剪切到HDFS:-moveFromLocal
⑥追加文件到已经存在文件末尾:-appendToFile
⑦显式文件内容:-cat
⑧-chgrp 、-chmod、-chown:Linux文件系统中的用法一样,修改文件所属权限
⑨从本地拷贝文件到HDFS:-copyFromLocal / -put
⑩从HDFS拷贝至本地:-copyToLocal / -get
(11)从HDFS的一个路径拷贝到HDFS的另一个路径:-cp
(12)在HDFS目录中剪切文件:-mv
(13)合并下载多个文件:-getmerge
(14)显示文件末尾:-tail
(15)删除文件:-rm
(16)统计文件夹的大小:-du
(17)设置HDFS中文件的副本数量:——setrep
三、HDFS客户端操作
1、参数设置的优先级
(1)客户端代码中设置的值 >(2)ClassPath下的用户自定义配置文件 >(3)然后是服务器的自定义配置(xxx-site.xml) >(4)服务器的默认配置(xxx-default.xml)
2、HDFS文件下载
//1 获取文件系统
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9820"), configuration, "JLUBJTU");
// 2 执行下载操作
// boolean delSrc 指是否将原文件删除
// Path src 指要下载的文件路径
// Path dst 指将文件下载到的路径
// boolean useRawLocalFileSystem 是否开启文件校验
fs.copyToLocalFile(false, new Path("/banzhang.txt"), new Path("e:/banzhang.txt"), true);
// 3 关闭资源
fs.close();
3、HDFS文件夹的删除
// 1 获取文件系统
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9820"), configuration, "JLUBJTU");
// 2 执行删除
fs.delete(new Path("/student/"), true);
// 3 关闭资源
fs.close();
4、HDFS文件名更改/移动
// 1 获取文件系统
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9820"), configuration, "JLUBJTU");
// 2 修改文件名称
fs.rename(new Path("/banzhang.txt"), new Path("/banhua.txt"));
// 3 关闭资源
fs.close();
5、HDFS文件详情查看
// 1获取文件系统
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9820"), configuration, "JLUBJTU");
// 2 获取文件详情
RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);
while (listFiles.hasNext()) {
LocatedFileStatus status = listFiles.next();
// 输出详情
// 文件名称
System.out.println(status.getPath().getName());
// 长度
System.out.println(status.getLen());
// 权限
System.out.println(status.getPermission());
// 分组
System.out.println(status.getGroup());
// 获取存储的块信息
BlockLocation[] blockLocations = status.getBlockLocations();
for (BlockLocation blockLocation : blockLocations) {
// 获取块存储的主机节点
String[] hosts = blockLocation.getHosts();
for (String host : hosts) {
System.out.println(host);
}
}
System.out.println("-----------漂亮的分割线----------");
}
// 3 关闭资源
fs.close();
6、HDFS文件和文件夹判断
// 1 获取文件配置信息
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop102:9820"), configuration, "JLUBJTU");
// 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的数据流
1、写数据流程
具体步骤为:
(1)客户端通过DistributedFileSystem模块向NameNode请求上传文件,NameNode检查目标文件是否已存在,父目录是否存在。
(2)NameNode返回是否可以上传。
(3) 客户端请求第一个 Block上传到哪几个DataNode服务器上。
(4)NameNode返回3个DataNode节点,分别为dn1、dn2、dn3。(默认存储3份)
(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步)。
机架感知:
2、读数据流程
1)客户端通过DistributedFileSystem向NameNode请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址。
2)挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据。
3)DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以Packet为单位来做校验)。
4)客户端以Packet为单位接收,先在本地缓存,然后写入目标文件。