Hadoop 之 HDFS

1 HDFS 概述

1.1 HDFS 产出背景及定义

随着数据量越来越大,在一个操作系统存不下所有的数据,那么就分配到更多的操作系统管理的磁盘中,但是不方便管理和维护,迫切需要一种系统来管理多台机器上的文件,这就是分布式文件管理系统。HDFS只是分布式文件管理系统中的一种。

HDFS(Hadoop Distributed File System),它是一个文件系统,用于存储文件,通过目录树来定位文件;其次,它是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色。

HDFS的使用场景:适合一次写入,多次读出的场景,且不支持文件的修改。适合用来做数据分析,并不适合用来做网盘应用。

1.2 HDFS优缺点

优点:

  • 高容错性
    • 数据自动保存多个副本。它通过增加副本的形式,提高容错性
    • 某一个副本丢失以后,它可以自动恢复
  • 适合处理大数据
  • 可构建在廉价机器上,通过多副本机制,提高可靠性

缺点:

  • 不适合低延时数据访问,比如毫秒级的存储数据
  • 无法高效的对大量小文件进行存储
  • 不支持并发写入、文件随机修改

1.3 HDFS组成架构

image
image

1.4 HDFS文件块大小

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

如果寻址时间为 100ms,即查找目标 Block 的时间是 100ms。

寻址时间与传输时间的比例为 100 : 1为最佳状态,因此传输时间为 1ms。

目前磁盘的传输速率大概在 100MB/s,取个整大概就是 128MB。

2 HDFS 的 Shell 操作

(1)-help:输出这个命令参数

(2)-ls:显示目录信息

(3)-mkdir:在 HDFS 上创建目录

(4)-moveFromLocal:从本地剪切粘贴到 HDFS

(5)-appendToFile:追加一个文件到已经存在的文件末尾

(6)-cat:显示文件内容

(7)-chgrp 、-chmod、-chown:Linux 文件系统中的用法一样,修改文件所属权限

(8)-copyFromLocal:从本地文件系统中拷贝文件到 HDFS 路径去

(9)-copyToLocal:从 HDFS 拷贝到本地

(10)-cp :从 HDFS 的一个路径拷贝到 HDFS 的另一个路径

(11)-mv:在 HDFS 目录中移动文件

(12)-get:等同于 copyToLocal,就是从 HDFS 下载文件到本地

(13)-getmerge:合并下载多个文件,比如 HDFS 的目录 /user/djm/test 下有多个文件:log.1, log.2,log.3,...

(14)-put:等同于 copyFromLocal

(15)-tail:显示一个文件的末尾

(16)-rm:删除文件或文件夹

(17)-rmdir:删除空目录

(18)-du:统计文件夹的大小信息

(19)-setrep:设置 HDFS 中文件的副本数量

3 HDFS 客户端操作

package com.djm.hdfsclient;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.net.URI;

public class HdfsClient {

    FileSystem fileSystem = null;

    @Before
    public void init() {

        try {
            fileSystem = FileSystem.get(URI.create("hdfs://hadoop102:9000"), new Configuration(), "djm");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 上传文件
     */
    @Test
    public void put() {
        try {
            fileSystem.copyFromLocalFile(new Path("C:\\Users\\Administrator\\Desktop\\Hadoop 入门.md"), new Path("/"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 下载文件
     */
    @Test
    public void download() {
        try {
            // useRawLocalFileSystem表示是否开启文件校验
            fileSystem.copyToLocalFile(false, new Path("/Hadoop 入门.md"), new Path("C:\\Users\\Administrator\\Desktop\\Hadoop 入门1.md"), true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除文件
     */
    @Test
    public void delete() {
        try {
            // recursive表示是否递归删除
            fileSystem.delete(new Path("/Hadoop 入门.md"), true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 文件重命名
     */
    @Test
    public void rename() {
        try {
            fileSystem.rename(new Path("/tmp"), new Path("/temp"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 查看文件信息
     */
    @Test
    public void ls() {
        try {
            RemoteIterator<locatedfilestatus> listFiles = fileSystem.listFiles(new Path("/etc"), true);
            while (listFiles.hasNext()) {
                LocatedFileStatus fileStatus = listFiles.next();
                if (fileStatus.isFile()) {
                    // 仅输出文件信息
                    System.out.print(fileStatus.getPath().getName() + "   " + fileStatus.getLen() + "   " + fileStatus.getPermission() + "   "  + fileStatus.getGroup() + "   ");
                    // 获取文件块信息
                    BlockLocation[] blockLocations = fileStatus.getBlockLocations();
                    for (BlockLocation blockLocation : blockLocations) {
                        // 获取节点信息
                        String[] hosts = blockLocation.getHosts();
                        for (String host : hosts) {
                            System.out.print(host + "   ");
                        }
                    }
                    System.out.println();
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @After
    public void exit() {
        try {
            fileSystem.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4 HDFS 的数据流

4.1 HDFS写数据流程

4.1.1 剖析文件写入

image

1、客户端通过 Distributed FileSystem 模块向 NameNode 请求上传文件,NameNode 检查目标文件是否已存在,父目录是否存在。

2、NameNode 返回是否可以上传。

3、客户端请求第一个 Block 上传到哪几个 DataNode。

4、NameNode 返回三个节点,分别是 dn1、dn2、dn3。

5、客户端通过 FSDataOutputStream 模块请求 dn1 上传数据,dn1 收到请求会继续调用 dn2,然后 dn2 调用 dn3,将这个通信管道建立完成。

6、按倒序逐级响应客户端。

7、客户端开始往 dn1 上传第一个 Block(先从磁盘读取数据放到一个本地内存缓存),以 Packet 为单位,dn1 收到一个Packet 就会传给 dn2,dn2 传给 dn3;dn1 每传一个 packet 会放入一个应答队列等待应答。

8、当一个Block传输完成之后,客户端再次请求NameNode上传第二个Block的服务器。

4.1.2 网络拓扑-节点距离计算

在HDFS写数据的过程中,NameNode会选择距离待上传数据最近距离的DataNode接收数据。那么这个最近距离怎么计算呢?

image

4.1.3 机架感知

image

4.2 HDFS读数据流程

image

1、客户端通过 Distributed FileSystem 向 NameNode 请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址。

2、根据就近原则挑选一台 DataNode,请求读取数据。

3、DataNode 开始传输数据给客户端。

4、客户端以 Packet 为单位接收,先在本地缓存,然后写入目标文件。

5 NameNode 和 SecondaryNameNode

5.1 NN 和 2NN 工作机制

如果存储在 NameNode 节点的磁盘中,因为经常需要进行随机访问,还有响应客户请求,必然是效率过低,因此,元数据必须存放在内存中,周所周知,内存的特点是速度快,断电后丢失数据,一旦断电,元数据丢失,整个集群就无法工作了,因此产生了用于备份元数据的 FsImage。

但是这样又会引发一个问题,当内存中的元数据更新时,FsImage 是否要同时更新,如果要同步更新,就会导致效率低,如果不同步更新,就会导致数据一致性问题,一旦突然断电,就会丢失一部分数据,因此,引入了 Edits(只进行追加操作,效率很高),每当元数据进行增加或者修改时,先追加到 Edits,在修改内存,这样的话,一旦断电,可以通过 FsImage 和 Edits 合成元数据。

但是,如果长时间添加数据到 Edits,导致 Edits 过大,还是会影响效率,而且一旦断电,恢复元数据的时间也会相应增加,因此,需要定期的对 FsImage 和 Edits 进行合并,如果这个操作由 NameNode 去完成,又会效率低(因为在合并后不能处理写请求),所以引入了 SecondaryNameNode,专门用来做合并操作。

image

NameNode 工作:

1、第一次启动 NameNode格式化后,创建 Fsimage 和 Edits 文件,如果不是第一次启动,直接加载编辑日志和镜像文件到内存。

2、客户端对元数据进行增删改操作。

3、NameNode 记录操作日志,更新滚动日志。

4、NameNode 在内存中对元数据进行增删改操作。

Secondary NameNode 工作:

1、Secondary NameNode 询问 NameNode 是否需要 CheckPoint,直接带回 NameNode 是否检查结果。

2、Secondary NameNode请求执行CheckPoint。

3、NameNode 滚动正在写的 Edits 日志。

4、将滚动前的编辑日志和镜像文件拷贝到 Secondary NameNode。

5、Secondary NameNode 加载编辑日志和镜像文件到内存合并。

6、生成新的镜像文件 fsimage.chkpoint。

7、拷贝 fsimage.chkpoint 到 NameNode。

8、NameNode 将 fsimage.chkpoint 重命名为 fsimage。

5.2 Fsimage 和 Edits 解析

image

oiv 查看Fsimage 文件

  • hdfs oiv -p 文件类型 -i镜像文件 -o 转换后文件输出路径

oev 查看 Edits 文件

  • hdfs oev -p 文件类型 -i编辑日志 -o 转换后文件输出路径

5.3 CheckPoint 时间设置

满足以下两个条件都会触发合并操作:

通常情况下,SecondaryNameNode 每隔一小时执行一次。

  • [hdfs-default.xml]

    <property>
      <name>dfs.namenode.checkpoint.period</name>
      <value>3600</value>
    </property>
    

一分钟检查一次操作次数,当次数到达 100 万次就会触发操作。

  • [hdfs-default.xml]

    <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>
    

5.4 NameNode 故障处理

NameNode 故障后,可以采用如下两种方法恢复数据:

将 2NN 中的数据拷贝到 NN 存储数据的目录。

使用 -importCheckpoint 选项启动 NN 守护进程,从而将 2NN 中数据拷贝到 NN 目录中。

  • hdfs namenode -importCheckpoint

5.5 集群安全模式

image

基本命令:

hdfs dfsadmin -safemode get:查看安全模式状态

hdfs dfsadmin -safemode enter:进入安全模式状态

hdfs dfsadmin -safemode leave:离开安全模式状态

hdfs dfsadmin -safemode wait:等待安全模式状态

6 DataNode

6.1 DataNode工作机制

image

1、一个数据块在 DataNode 上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳。

2、DataNode 启动后向 NameNode 注册,通过后,周期性(1小时)的向 NameNode 上报所有的块信息。

3、心跳是每 3 秒一次,心跳返回结果带有 NameNode 给该 DataNode 的命令如复制块数据到另一台机器,或删除某个数据块,如果超过 10 分钟没有收到某个 DataNode 的心跳,则认为该节点不可用。

4、集群运行中可以安全加入和退出一些机器。

6.2 数据完整性

image

1、当 DataNode 读取 Block 的时候,它会计算 CheckSum。

2、如果计算后的 CheckSum,与 Block 创建时值不一样,说明 Block 已经损坏。

3、Client 读取其他 DataNode 上的 Block。

4、在其文件创建后周期验证。

6.3 掉线时限参数设置

image

[hdfs-site.xml]

<property>
    <name>dfs.namenode.heartbeat.recheck-interval</name>
    <value>300000</value>
    <description>毫秒</description>
</property>
<property>
    <name>dfs.heartbeat.interval</name>
    <value>3</value>
    <description>秒</description>
</property>

6.4 服役新数据节点

将 hadoop102 上的 java、hadoop、profile 发送到新主机,source 一下 profile,直接启动即可加入集群。

6.5 退役旧数据节点

6.5.1 黑名单设置

创建黑名单

[djm@hadoop101 hadoop]$ touch blacklist 

配置加入黑名单的主机

hadoop102

配置 hdfs-site.xml

<property>
    <name>dfs.hosts.exclude</name>
    <value>/opt/module/hadoop-2.7.2/etc/hadoop/blacklist</value>
</property>

刷新 namenodes

[djm@hadoop102 hadoop-2.7.2]$ hdfs dfsadmin -refreshNodes

更新 ResourceManager 节点

[djm@hadoop102 hadoop-2.7.2]$ yarn rmadmin -refreshNodes

如果数据不均衡,可以用命令实现集群的再平衡

[djm@hadoop102 hadoop-2.7.2]$ start-balancer.sh

6.5.2 白名单设置

创建白名单

[djm@hadoop101 hadoop]$ touch whitelist 

配置加入黑名单的主机

hadoop102
hadoop103
hadoop104

配置 hdfs-site.xml

<property>
    <name>dfs.hosts</name>
    <value>/opt/module/hadoop-2.7.2/etc/hadoop/whitelist</value>
</property>

刷新 namenodes

[djm@hadoop102 hadoop-2.7.2]$ hdfs dfsadmin -refreshNodes

更新 ResourceManager 节点

[djm@hadoop102 hadoop-2.7.2]$ yarn rmadmin -refreshNodes

如果数据不均衡,可以用命令实现集群的再平衡

[djm@hadoop102 hadoop-2.7.2]$ start-balancer.sh

黑白名单的区别:

白名单比较严格,黑名单比较平缓,处于黑名单中的主机会同步数据结束后继续处于集群,只是不在处理请求而已,而不处于白名单中的主机会直接被干掉。

6.6 Datanode多目录配置

DataNode也可以配置成多个目录,每个目录存储的数据不一样,即:数据不是副本。

hdfs-site.xml

<property>
    <name>dfs.datanode.data.dir</name>
    <value>file:///${hadoop.tmp.dir}/dfs/data1,file:///${hadoop.tmp.dir}/dfs/data2</value>
</property>

7 HDFS 2.X新特性

7.1 集群间数据拷贝

采用 distcp 命令实现两个 Hadoop 集群之间的递归数据复制

[djm@hadoop102 hadoop-2.7.2]$  hadoop distcp hdfs://haoop102:9000/user/djm/hello.txt hdfs://hadoop103:9000/user/djm/hello.txt

7.2 小文件存档

image

归档文件

[djm@hadoop102 hadoop-2.7.2]$ hadoop archive -archiveName input.har –p  /user/djm/input   /user/djm/output

查看归档

[djm@hadoop102 hadoop-2.7.2]$ hadoop fs -lsr har:///user/djm/output/input.har

解归档文件

[atguigu@djm hadoop-2.7.2]$ hadoop fs -cp har:/// user/djm/output/input.har/*    /user/djm

</locatedfilestatus>

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

推荐阅读更多精彩内容

  • Hadoop分布式文件系统(HDFS)是一种分布式文件系统。它与现有的分布式文件系统有许多相似之处。但是,与其他分...
    逍遥ii阅读 1,127评论 3 20
  • 第1章 HDFS概述 1.1 HDFS定义 HDFS(Hadoop distributed System),它是一...
    白纸糊阅读 340评论 0 0
  • 我们依然是先过一遍官方文档: 引言Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodi...
    e5bda6e7a596阅读 685评论 0 0
  • hdfs是什么? 问题: 1. hdfs是基于什么样的原理将文件分块存储到分布式环境中的各个设备上的? 2. h...
    4762d2980c91阅读 4,646评论 0 6
  • 【亲子时间管理90天践行】打卡模版 打卡人:林琳 打卡日期:2018/5/24 打卡累积天数:15/30 我的宣言...
    林子Amy阅读 96评论 0 0