一、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为单位接收,先在本地缓存,然后写入目标文件。
五、NameNode和SecondaryNameNode
1、NN和2NN的工作机制
NameNode中的元数据因为要时常随即访问,因此必须放在内存中,但是为了安全,需要在磁盘中备份元数据FsImage。
当内存数据更新时,如果同时更新FsImage,效率低,若不更新,则会发生数据不一致问题,因此引入Edits文件(只追加),每当元数据有更新或者添加元数据时,修改内存中的元数据并追加到Edits中。这样,一旦NameNode节点断电,可以通过FsImage和Edits的合并,合成元数据。
但是时间长了,Edits会过大。需要定期进行FsImage和Edits的合并,如果这个操作由NameNode节点完成,又会效率过低。因此,引入一个新的节点SecondaryNamenode,专门用于FsImage和Edits的合并。
2、CheckPoint时间设置
通常情况下,SecondaryNameNode每隔一小时执行一次。
[hdfs-default.xml]
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>3600</value>
</property>
CheckPoint中触发的数据条件:
操作数大于1000000,进行合并。
<property>
<name>dfs.namenode.checkpoint.txns</name>
<value>1000000</value>
<description>操作动作次数</description>
</property>
<property>
<name>dfs.namenode.checkpoint.check.period</name>
<value>60</value>
<description> 1分钟检查一次操作次数</description>
</property >
3、集群的安全模式
如果满足“最小副本条件”,NameNode会在30秒钟之后就退出安全模式。所谓的最小副本条件指的是在整个文件系统中99.9%的块满足最小副本级别(默认值: dfs.replication.min=1) 。在启动一个刚刚格式化的HDFS集群时,因为系统中还没有任何块,所以NameNode不会进 入安全模式。
(1)bin/hdfs dfsadmin -safemode get (功能描述:查看安全模式状态)
(2)bin/hdfs dfsadmin -safemode enter (功能描述:进入安全模式状态)
(3)bin/hdfs dfsadmin -safemode leave (功能描述:离开安全模式状态)
(4)bin/hdfs dfsadmin -safemode wait (功能描述:等待安全模式状态)
六、DataNode
1、DN工作机制
2、服役新的数据节点
配置core-site.xml,设置NM,RM的地址,直接启动DataNode,即可关联到集群
3、退役旧节点
在NameNode的/opt/module/hadoop-3.1.3/etc/hadoop目录下分别创建whitelist 和blacklist文件。
在NameNode的hdfs-site.xml配置文件中增加dfs.hosts 和 dfs.hosts.exclude配置。
<property>
<name>dfs.hosts</name>
<value>/opt/module/hadoop-3.1.3/etc/hadoop/whitelist</value>
</property>
<property>
<name>dfs.hosts.exclude</name>
<value>/opt/module/hadoop-3.1.3/etc/hadoop/blacklist</value>
</property>
将配置文件分发至所有节点。重启集群。
黑名单:
在blacklist中添加黑名单,并刷新NameNode,这些节点便会退役,有数据的迁移。
hdfs dfsadmin -refreshNodes
白名单:(不推荐)
白名单退役会直接将节点抛弃,没有迁移数据的过程,会造成数据丢失。不在白名单范围内的节点无法访问集群。
4、DN的多目录配置
在hdfs-site.xml中修改如下内容:
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///${hadoop.tmp.dir}/data1,file:///${hadoop.tmp.dir}/data2</value>
</property>
配置了两个DN的地址,这两个不是副本的关系。
七、小文件的存档
小文件的危害:
1、耗尽NameNode的内存,
2、会又很多的Map进程
解决方法之一:
HDFS存档文件或HAR文件,是一个更高效的文件存档工具,它将文件存入HDFS块,在减少NameNode内存使用的同时,允许对文件进行透明的访问。具体说来,HDFS存档文件对内还是一个一个独立文件,对NameNode而言却是一 个整体, 减少了NameNode的内存。
eg:
把/user/input目录里面的所有文件归档成一个叫input.har的归档文件,并把归档后文件存储到/user/output路径下。
[SQLBoy@hadoop102 hadoop-3.1.3]$ hadoop archive -archiveName input.har –p /user/input /user/output
查看归档
[SQLBoy@hadoop102 hadoop-3.1.3]$ hadoop fs -lsr /user/output/input.har
[SQLBoy@hadoop102 hadoop-3.1.3]$ hadoop fs -lsr har:///user/output/input.har
解归档文件
[SQLBoy@hadoop102 hadoop-3.1.3]$ hadoop fs -cp har:/// user/output/input.har/* /user