Hadoop,HDFS原理及操作

今天来聊下Hadoop和HDFS。

1、Hadoop介绍

1.1、Hadoop是什么?

Hadoop是一个由Apache基金会所开发的分布式系统基础架构。主要解决海量数据的存储和海量数据的分析计算问题。

1.2、Hadoop发展历史

Hadoop的雏形是由Doug Cutting等人借鉴Google在大数据方面的三篇论文后(GFS->HDFS,MapReduce->MR,BigTable->HBase),用了2年业余时间实现的,后来被引入Apache基金会立项,2006年3月Hadoop正式诞生,标志着大数据时代来临。名字来源于Doug Cutting儿子的玩具大象。


1.3、Hadoop三大发行版本

Apache版本是最原始最基础的版本,开源免费。
Cloudera内部集成了很多大数据框架,对应产品CDH,收费,每年每个节点10000美元。
Hortonworks文档较好,对应产品HDP,目前已被Cloudera公司收购。

1.4、Hadoop的优势

  • 高可靠性:Hadoop底层维护多个数据副本,即使Hadoop某个计算元素或存储出现故障,也不会导致数据丢失。
  • 高扩展性:在集群间分配任务数据,可方便的扩展数以千计的节点。
  • 高效性:在MapReduce的思想下,Hadoop是并行工作的,以加快任务处理速度。
  • 高容错性:能够自动将失败的任务重新分配。

1.5、Hadoop的组成

Hadoop2.x和3.x都由HDFS、MapReduce和Yarn组成。HDFS负责数据存储,MapReduce负责计算,Yarn负责资源调度。



在Hadoop1.x时代,Hadoop中的MapReduce同时处理业务逻辑运算和资源的调度,耦合性较大,在Hadoop2.x时代增加了Yarn,Yarn只负责资源的调度,MapReduce只负责运算。

Hadoop各组成介绍:

  • HDFS:HDFS由NameNode、DataNode和Secondary NameNode组成。NameNode存储文件的元数据,DataNode存储文件块数据,Secondary NameNode每隔一段时间对NameNode元数据备份。
  • MapReduce:MapReduce将计算过程分成两个阶段,Map阶段和Reduce阶段,Map阶段并行处理输入数据,Reduce阶段对Map结果进行汇总。
  • Yarn:Yarn由ResourceManager、NodeManager、ApplicationMaster和Container组成。

2、HDFS介绍

2.1、HDFS概述

随着数据量越来越大,需要一种系统来管理多台机器上的文件,就是分布式文件管理系统,其中HDFS只是分布式文件管理系统的一种。

HDFS全称是Hadoop Distributed File System,它是一个文件系统,用来存储文件,通过目录树来定位文件,其次它是分布式的,由很多服务器联合起来实现功能。

由于HDFS是分布式的,不难想到它的使用场景,适合一次写入,多次读出的场景,且不支持文件的修改

HDFS优点:高容错性、适合处理大数据、可构建在廉价机器上。
HDFS缺点:不适合低延时数据访问(比如毫秒级存储数据做不到)、无法高效的对大量小文件进行存储、不支持并发写入和文件随机修改(仅支持数据追加)。

HDFS组织架构如下:



NameNode--就是Master,管理者,下达命令

  • 管理HDFS的的名称空间。
  • 配置副本策略。
  • 管理数据块映射信息。
  • 处理客户端读写请求。
    DataNode--就是Salve,执行命令
  • 存储实际的数据块。
  • 执行数据块的读/写操作。
    Client--客户端
  • 将文件切分为多个Block。
  • 与NameNode、DataNode交互。
  • 可以通过一些命令管理和访问HDFS。
    Secondary NameNode
  • 辅助NameNode。
  • 辅助恢复NameNode。

HDFS中的文件在物理上是分块存储的,块的大小可以通过配置参数(dfs.blocksize)来规定,默认大小在Hadoop2.x版本中是128M,旧版本中是64M。

根据经验公式当寻址时间为传输时间的1%时为最佳状态,那么寻址时间是10ms时传输时间就是1s,而目前磁盘的传输速率普遍为100MB/s,得到block大小为100MB,取整数就是128M(对于计算机而言的整数)。

块太小会增加寻址时间。块太大则从磁盘传输数据的时间会明显大于定位块开始位置的时间,导致处理块数据速度变慢。

HDFS块的大小设置主要取决于磁盘传输速度。

2.2、HDFS的Shell操作

2.2.1、基本语法

bin/hadoop fs 具体命令
bin/hdfs dfs 具体命令

有环境变量可不用加路径bin/

2.2.2、常用命令实操

hadoop fs -help rm # 输出这个命令参数

上传:

hadoop fs -moveFromLocal ./test01.txt /files # 从本地剪切粘贴到HDFS
hadoop fs -copyFromLocal ./test02.txt /files # 从本地拷贝到HDFS
hadoop fs -appendToFile ./test03.txt /files/test02.txt # 追加一个文件到已经存在的文件末尾
hadoop fs -put ./test04.txt /files # 等同于copyFromLocal

下载:

hadoop fs -copyToLocal /files/test01.txt ./ # 从HDFS拷贝到本地
hadoop fs -get /files/test02.txt ./ # 等同于copyToLocal
hadoop fs -getmerge /files/* ./merge.txt # 合并下载多个文件

HDFS直接操作:

hadoop fs -ls / # 显示目录树
hadoop fs -mkdir -p /files/create/ # 在HDFS上创建目录
hadoop fs -cat /files/test01.txt # 显示文件内容
hadoop fs -chmod 777 /files/test02.txt # 修改文件所属权限
hadoop fs -chown dgf:dgf /files/test03.txt # 修改文件拥有者
hadoop fs -cp /files/test04.txt /files/create/ # 从HDFS一个路径拷贝到另一个路径
hadoop fs -mv /files/test05.txt /files/create/ # 在HDFS目录中移动文件
hadoop fs -tail /files/test06.txt # 显示一个文件的末尾
hadoop fs -rm /files/test07.txt # 删除文件或文件夹
hadoop fs -rmdir /test # 删除空目录
hadoop fs -du -s -h /files/create # 只统计文件夹的大小信息
hadoop fs -du -h /files/create # 统计文件夹下各文件的大小信息
hadoop fs -setrep 6 /files/test08.txt # 设置HDFS中文件的副本数量
# 这里设置的副本数只是记录在NameNode的元数据中,是否真有这么多副本还得看DataNode的数量

2.3、HDFS客户端操作

2.3.1、客户端环境准备

将windows依赖拷贝到系统,然后配置环境变量,最后重启下电脑。

创建Maven工程并添加依赖:

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>2.16.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-client</artifactId>
        <version>3.1.3</version>
    </dependency>
</dependencies>

创建HdfsClient类:

public class HdfsClient{  
    @Test
    public void testMkdirs() throws IOException, InterruptedException, URISyntaxException{
            //1.获取文件系统
            Configuration configuration = new Configuration();
            //配置在集群上运行
            //configuration.set("fs.defaultFS", "hdfs://hadoop1:9820");
            //FileSystem fs = FileSystem.get(configuration);
            FileSystem fs = FileSystem.get(new URI("hdfs://hadoop1:9820"), configuration, "dgf");
            //2.创建目录
            fs.mkdirs(new Path("/files/create/files"));
            //3.关闭资源
            fs.close();
    }
}

配置用户名称并执行程序:



客户端操作HDFS时,是有一个用户身份的,默认情况下,HDFS客户端API会从JVM中获取一个参数作为自己的用户身份:-DHADOOP_USER_NAME=dgf,dgf为用户名称。

2.3.2、HDFS API操作

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://hadoop1:9820"), configuration, "dgf");
        //2.上传文件
        fs.copyFromLocalFile(new Path("e:/test.txt"), new Path("/test.txt"));
        //3.关闭资源
        fs.close();
        System.out.println("over");
}

参数优先级:客户端代码>工程配置文件>服务器默认配置。

HDFS文件下载:

@Test
public void testCopyToLocalFile() throws IOException, InterruptedException, URISyntaxException{
        //1.获取文件系统
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://hadoop1:9820"), configuration, "dgf");
        //2.执行下载操作
        //boolean delSrc 指是否将原文件删除
        //Path src 指要下载的文件路径
        //Path dst 指将文件下载到的路径
        //boolean useRawLocalFileSystem 是否开启文件校验
        fs.copyToLocalFile(false, new Path("/test.txt"), new Path("e:/test.txt"), true);
        //3.关闭资源
        fs.close();
}

通过流向HDFS上传和下载文件:

//上传
@Test
public void test01() throws Exception {
    //创建输入流读取本地文件的内容
    FileInputStream fis = new FileInputStream(new Path("E:\\test.txt"));
    //创建输出流将文件写到HDFS上
    FSDataOutputStream fos = fs.create(new Path("/test.txt"));
    //文件对拷
    IOUtils.copyBytes(fis,fos,2000);
    //关闭流
    IOUtils.closeStream(fis);
    IOUtils.closeStream(fos);
}
//下载
@Test
public void test02() throws Exception {
    FSDataInputStream fis = fs.open(new Path("/test.txt"));
    FileOutputStream fos = new FileOutputStream(new Path("E://test.txt"));
    //最后一个参数 :true就会关流 false不会关流
    IOUtils.copyBytes(fis,fos,2000,true);
}

2.4、HDFS的数据流

2.4.1、HDFS读数据流程

  1. 客户端通过Distributed FileSystem向NameNode请求下载文件。
  2. NameNode通过查询元数据,找到文件块所在的DataNode地址,返回目标文件的元数据。
  3. 挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据。
  4. DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以Packet为单位来做校验)。
  5. 客户端以Packet为单位接收,先在本地缓存,然后写入目标文件。

2.4.2、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步)。

在HDFS写数据的过程中,NameNode会选择距离待上传数据最近距离的DataNode接受数据。下面介绍下节点距离的计算。


节点距离:两个节点到达最近的共同祖先的距离总和。

副本节点的选择:


  • 第一个副本在Client所处的节点上,如果客户端在集群外,随机选一个。
  • 第二个副本在另一个机架的随机一个节点。
  • 第三个副本在第二个副本所在机架的随机节点。

以上介绍了HDFS的读写流程和实际操作命令,关于HDFS的组成这里先不做介绍。
今天的内容就到这里,下篇见。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容