hdfs应用
1. hdfs概述
1.1 产生背景
随着数据量越来越大,在一个操作系统存不下所有的数据,那么就分配到更多的操作系统管理的磁盘中,但是不方便管理和维护,迫切需要一种系统来管理多台机器上的文件,这就是分布式文件管理系统。HDFS只是分布式文件管理系统中的一种。
1.2 什么是hdfs
HDFS(Hadoop Distributed File System),它是一个文件系统,用于存储文件,通过目录树来定位文件;其次,它是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色。
HDFS的使用场景:适合一次写入,多次读出的场景,且不支持文件的修改。适合用来做数据分析,并不适合用来做网盘应用。
1.3 hdfs优点
高容错性
适合处理大数据
数据规模:能够处理数据规模达到GB、TB、甚至PB级别的数据;
文件规模:能够处理百万规模以上的文件数量,数量相当之大。
可构建在廉价机器上,通过多副本机制,提高可靠性
1.4 hdfs缺点
1)不适合低延时数据访问,比如毫秒级的存储数据,是做不到的。
2)无法高效的对大量小文件进行存储。
(1)存储大量小文件的话,它会占用NameNode大量的内存来存储文件目录和块信息。这样是不可取的,因为NameNode的内存总是有限的; 因namenode将文件系统的元数据存放在内存中,因此存储的文件数目受限于 namenode的内存大小。HDFS中每个文件、目录、数据块占用150Bytes。如果存放的文件数目过多的话会占用很大的内存
(2)小文件存储的寻址时间会超过读取时间,它违反了HDFS的设计目标。
3)不支持并发写入、文件随机修改。
(1)一个文件只能有一个写,不允许多个线程同时写;
(2)仅支持数据append(追加),不支持文件的随机修改。
2. hdfs架构
2.1 hdfs架构
2.2 Namenode节点
NameNode(nn):就是Master,它是一个主管、管理者。
(1)管理HDFS的名称空间;
(2)配置副本策略;
(3)管理数据块(Block)映射信息;
(4)处理客户端读写请求。
2.3 datanode节点
DataNode:就是Slave。NameNode下达命令,DataNode执行实际的操作。
(1)存储实际的数据块;
(2)执行数据块的读/写操作。
2.4 客户端
(1)文件切分。文件上传HDFS的时候,Client将文件切分成一个一个的Block,然后进行上传;
(2)与NameNode交互,获取文件的位置信息;
(3)与DataNode交互,读取或者写入数据;
(4)Client提供一些命令来管理HDFS,比如NameNode格式化;
(5)Client可以通过一些命令来访问HDFS,比如对HDFS增删查改操作;
2.5 Secondary NameNode
Secondary NameNode:并非NameNode的热备。当NameNode挂掉的时候,它并不能马上替换NameNode并提供服务。
(1)辅助NameNode,分担其工作量,比如定期合并Fsimage和Edits,并推送给NameNode ;
(2)在紧急情况下,可辅助恢复NameNode。
2.6 Fsimage和Edits是什么
fsimage:HDFS文件系统元数据的镜像文件,其中包含HDFS文件系统的所有目录和文件inode及相关属性的序列化信息。
edits:用户操作的编辑日志文件,存放HDFS文件系统的所有更新操作的动作,文件所有写操作会被记录到Edits文件中。
在namenode运行期间, 客户端对hdfs的写操作都保存到edit文件中, 久而久之就会造成edit文件变得很大, 如果namenode重启, 它会将fsimage中的内容映射到内存中, 然后再一条一条执行edit文件中的操作, 所以日志文件太大会导致重启速度很慢。所以在namenode运行的时候就要将edit logs和fsimage定期合并。
3. 数据块
HDFS中的文件在物理上是分块存储(Block),块的大小可以通过配置参数( dfs.blocksize)来规定,默认大小在Hadoop2.x版本中是128M,老版本中是64M。
4. HDFS的Shell操作
4.1 基本语法
hadoop fs 具体命令 OR hdfs dfs 具体命令,两个是完全相同的。
4.2 命令大全
[hadoop@hadoop-001 hadoop-3.1.3]$ bin/hadoop fs
[-appendToFile
[-cat [-ignoreCrc]
[-checksum
[-chgrp [-R] GROUP PATH...]
[-chmod [-R]
[-chown [-R] [OWNER][:[GROUP]] PATH...]
[-copyFromLocal [-f] [-p]
[-copyToLocal [-p] [-ignoreCrc] [-crc]
[-count [-q]
[-cp [-f] [-p]
[-createSnapshot
[-deleteSnapshot
[-df [-h] [
[-du [-s] [-h]
[-expunge]
[-get [-p] [-ignoreCrc] [-crc]
[-getfacl [-R]
[-getmerge [-nl]
[-help [cmd ...]]
[-ls [-d] [-h] [-R] [
[-mkdir [-p]
[-moveFromLocal
[-moveToLocal
[-mv
[-put [-f] [-p]
[-renameSnapshot
[-rm [-f] [-r|-R] [-skipTrash]
[-rmdir [--ignore-fail-on-non-empty]
[-setfacl [-R] [{-b|-k} {-m|-x
[-setrep [-R] [-w]
[-stat [format]
[-tail [-f]
[-test -[defsz]
[-text [-ignoreCrc]
[-touchz
[-usage [cmd ...]]
4.3 HDFS直接操作
1)-ls: 显示目录信息
[hadoop@hadoop-001 hadoop-3.1.3]$ hadoop fs -ls /
2)-mkdir:在HDFS上创建目录
[hadoop@hadoop-001 hadoop-3.1.3]$ hadoop fs -mkdir -p /sanguo/shuguo
3)-cat:显示文件内容
[hadoop@hadoop-001 hadoop-3.1.3]$ hadoop fs -cat /sanguo/shuguo/kongming.txt
4)-chgrp 、-chmod、-chown:Linux文件系统中的用法一样,修改文件所属权限
指令中的a、b、c分别表示一个数字,其中a对应文件所有者权限,b对应文件所有者所在组权限,c对应其他身份权限。
对于a、b、c各自来讲,它们都是0~7的数字,对应r、w、x三个二进制位按序组成的二进制数,举个例子,如果是只可读,对应的二进制数就是“100”,也就是4;如果是可读可写不可执行,那么对应二进制数为“110”,也就是6。
666表示所有用户可读可写。
[hadoop@hadoop-001 hadoop-3.1.3]$ hadoop fs -chmod 666 /sanguo/shuguo/kongming.txt
[hadoop@hadoop-001 hadoop-3.1.3]$ hadoop fs -chown hadoop:hadoop /sanguo/shuguo/kongming.txt
5)-cp :从HDFS的一个路径拷贝到HDFS的另一个路径
[hadoop@hadoop-001 hadoop-3.1.3]$ hadoop fs -cp /sanguo/shuguo/kongming.txt /zhuge.txt
6)-mv:在HDFS目录中移动文件
[hadoop@hadoop-001 hadoop-3.1.3]$ hadoop fs -mv /zhuge.txt /sanguo/shuguo/
7)-tail:显示一个文件的末尾1kb的数据
[hadoop@hadoop-001 hadoop-3.1.3]$ hadoop fs -tail /sanguo/shuguo/kongming.txt
8)-rm:删除文件或文件夹
[hadoop@hadoop-001 hadoop-3.1.3]$ hadoop fs -rm /user/hadoop/test/jinlian2.txt
9)-rmdir:删除空目录
[hadoop@hadoop-001 hadoop-3.1.3]$ hadoop fs -mkdir /test
[hadoop@hadoop-001 hadoop-3.1.3]$ hadoop fs -rmdir /test
10)-du统计文件夹的大小信息
-h按照适合阅读的形式人性化显示文件大小
[hadoop@hadoop-001 hadoop-3.1.3]$ hadoop fs -du -h /user/hadoop/test
1.3 K /user/hadoop/test/README.txt
1.4 K /user/hadoop/test/zaiyiqi.txt
-s 查看指定文件夹大小信息
[hadoop@hadoop-001 hadoop-3.1.3]$ hadoop fs -du -s -h /user/hadoop/test
2.7 K /user/hadoop/test
11)-setrep:设置HDFS中文件的副本数量
[hadoop@hadoop-001 hadoop-3.1.3]$ hadoop fs -setrep 10 /sanguo/shuguo/kongming.txt
这里设置的副本数只是记录在NameNode的元数据中,是否真的会有这么多副本,还得看DataNode的数量。因为目前只有3台设备,最多也就3个副本,只有节点数的增加到10台时,副本数才能达到10。
5. HDFS客户端操作
5.1 准备Windows关于Hadoop的开发环境
1)找到资料目录下的Windows依赖目录,打开:
选择Hadoop-3.1.0,拷贝到其他地方(比如d:)。
2)配置HADOOP_HOME环境变量。
3)配置Path环境变量
5.2 创建maven工程
4)创建一个Maven工程HdfsClientDemo,并导入相应的依赖坐标+日志添加
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
在项目的src/main/resources目录下,新建一个文件,命名为“log4j2.xml”,在文件中填入
pattern="[%p] [%d{yyyy-MM-dd HH:mm:ss}][%c{10}]%m%n" /> 5.3 创建HdfsClient类 package com.peng.hdfs public class HdfsClient{ @Test public void testMkdirs() throws IOException, InterruptedException, URISyntaxException{ // 1 获取文件系统 Configuration configuration = new Configuration(); // 配置在集群上运行 // configuration.set("fs.defaultFS", "hdfs://hadoop102:9820"); // FileSystem fs = FileSystem.get(configuration); FileSystem fs = FileSystem.get(new URI("hdfs://hadoop-001:9820"), configuration, "hadoop"); // 2 创建目录 fs.mkdirs(new Path("/1108/daxian/banzhang")); // 3 关闭资源 fs.close(); } } 5.4 运行时需要配置用户名称 运行时需要配置用户名称 客户端去操作HDFS时,是有一个用户身份的。默认情况下,HDFS客户端API会从JVM中获取一个参数来作为自己的用户身份:-DHADOOP_USER_NAME=hadoop,hadoop为用户名称。 5.5 HDFS文件上传(测试参数优先级) 编写源代码 @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://hadoop-001:9820"), configuration, "hadoop"); // 2 上传文件 fs.copyFromLocalFile(new Path("D:/wc/wc.txt"), new Path("/wc.txt")); // 3 关闭资源 fs.close(); System.out.println("over"); } 5.6 HDFS文件下载 编写源代码 @Test public void testCopyToLocalFile() throws IOException, InterruptedException, URISyntaxException{ // 1 获取文件系统 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://hadoop-001:9820"), configuration, "hadoop"); // 2 执行下载操作 // boolean delSrc 指是否将原文件删除 // Path src 指要下载的文件路径 // Path dst 指将文件下载到的路径 // boolean useRawLocalFileSystem 是否开启文件校验 fs.copyToLocalFile(false, new Path("/wc.txt"), new Path("d:/wc/wc.txt"), true); // 3 关闭资源 fs.close(); } 5.7 HDFS删除文件和目录 编写源代码 @Test public void testDelete() throws IOException, InterruptedException, URISyntaxException{ // 1 获取文件系统 Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://hadoop-001:9820"), configuration, "hadoop"); // 2 执行删除 fs.delete(new Path("/1108/"), true); // 3 关闭资源 fs.close(); } 6. HDFS写数据流程 (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步)。 7. HDFS读数据流程 (1)客户端通过DistributedFileSystem向NameNode请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址。 (2)挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据。 (3)DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以Packet为单位来做校验)。 (4)客户端以Packet为单位接收,先在本地缓存,然后写入目标文件。