【十八掌●内功篇】第五掌:HDFS之基础知识

这一篇博文是【大数据技术●降龙十八掌】系列文章的其中一篇,点击查看目录:这里写图片描述大数据技术●降龙十八掌


系列文章:
【十八掌●内功篇】第五掌:HDFS之基础知识
【十八掌●内功篇】第五掌:HDFS之Shell

一、 HDFS简介

1、 Hadoop中的HDFS

HDFS是Hadoop Distributed File System(Hadoop 分布式文件系统)的缩写,但是HDFS不是Hadoop里的唯一的分布式文件系统,因为Hadoop只是定义了文件系统的抽象,HDFS只是其中的一个实现,另外,Hadoop中支持的文件系统如下:

文件系统URI方案Java实现定义
Localfilefs.LocalFileSystem支持有客户端校验和的本地文件系统
HDFShdfshdfs.DistributedFileSystemHadoop的分布式文件系统
HFTPhftphdfs.HftpFilesSystem支持通过Http方式以只读的方式访问HDFS,distcp经常用在不同的HDFS集群间复制数据
HSFTPhsftphdfs.HsftpFilesSystem支持通过Https方式以只读的方式访问HDFS
HARharfs.HarFileSystem构建在其他文件系统上进行归档文件的文件系统,Hadoop归档文件主要用来减少NameNode的内存使用。
KFSkfsfs.kfs.KosmosFilesSystem
FTPftpFs.ftp.FtpFileSystem由FTP服务器支持的文件系统
S3(本地)s3nfs.s3native.NativeS3FileSystem基于AmazonS3的文件系统
S3(基于块)s3fs.s3.NativeS3FileSystem基于AmazonS3的文件系统,以块格式存储解决了S3的5GB文件大小的限制
2、 HDFS的特点

HDFS是基于流数据模式访问和处理超大文件的需求而开发的,HDFS的主要特点

(1) 超大文件数据集群

HDFS可以存储和管理GB、TB、甚至PB级别的大文件。

(2) 流式数据访问方式读取文件

HDFS的设计是基于“一次写入、多次读取”任务,对文件的读取,是采用顺序全部扫描的方式。

(3) 对硬件要求并不是特别高,有很好的容错机制。

因为HDFS在设计上考虑了数据的可靠性、安全性、高可用性,所以HDFS对硬件的要求并不是太高,可以运行在廉价的商用硬件集群上。

(4) 数据访问有一定的延迟

HDFS适合大型数据集的分析人物,HDFS优化的是数据吞吐量,是要以提高延迟为代价的。
(5) HDFS无法高效存储大量小文件

因为HDFS上所有文件的元数据都是存储在NameNode上的,而NameNode数据是存在内存里的,所以NameNode的内存大小限制了文件个数。

(6) HDFS不支持多个写入者,也不支持随机写。

HDFS的一个文件只有一个写入者,并且操作只能在文件末尾追加,所以不支持随机写。

二、 HDFS体系结构

1、 体系结构图

在这里插入图片描述

2、 体系结构介绍

(1) HDFS由Client、NameNode、DataNode、SecondaryNameNode组成。

(2) Client提供了文件系统的调用接口。

(3)NameNode由fsimage(HDFS元数据镜像文件)和editlog(HDFS文件改动
日志)组成,NameNode在内存中保存着每个文件和数据块的引用关系。
NameNode中的引用关系不存在硬盘中,每次都是HDFS启动时重新构造
出来的。
(4) SecondaryNameNode的任务有两个:

定期合并fsimage和editlog,并传输给NameNode。

为NameNode提供热备份。

(5) 一般是一个机器上安装一个DataNode,一个DataNode上又分为很多

很多数据块(block)。

(6) DataNode会通过心跳定时向NameNode发送所存储的文件块信息。

(7) HDFS的副本存放规则

默认的副本系数是3,一个副本存在本地机架的本机器上,第二个副本存
储在本地机架的其他机器上,第三个副本存在其他机架的一个节点上。
这样减少了写操作的网络数据传输,提高了写操作的效率;另一方面,机
架的错误率远比节点的错误率低,所以不影响数据的可靠性。

3、 核心概念

(1) 块

数据块是HDFS中最小的寻址单位,Hadoop2.5中默认一个块的大小为
128M,不像其他的文件系统,HDFS中块是个逻辑概念,少于一个块大小
的文件不会占用一整块的空间。
设置块比较大的原因是减少寻址开销,但是块设置的也不能过大,因为一
个Map任务一般是处理一个块的数据,如果块设置的太大,Map任务处理的数据
量就会过大,会导致效率并不高

HDFS中块是逻辑概念的好处:

  • 可以存储任意大的文件而不受单个节点磁盘大小的限制,HDFS可以将超
    大文件分割为多个块,分别存储在不同的机器上。

  • 简化存储子系统的设计,权限信息和块分开存储,利于管理。

  • 块的设计利于数据备份,进而提供容错能力和提高可用性。

(2) NameNode

NameNode管理集群中的文件读写执行调度,并存储文件的元数据,NameNode的
数据存储在命名空间镜像(Namespace image)和编辑日志(Edit log)
中,NameNode启动时,会将所有数据读取到内存中

(3) DataNode

DataNode负责任务的执行,并存储数据,和客户端进行交互,DataNode
会通过心跳定时向NameNode发送它所存储的块信息。

(4) HDFS联盟

HDFS集群中只有一个NameNode是有很多局限性的,为了解决单个
NameNode的局限,设计了HDFS联盟,HDFS 联盟是可以在Hadoop集群
中设置多个NameNode,联盟中的多个NameNode是不同的,可以理解为
将一个NameNode切分为了多个NameNode,每一个NameNode只负责管
理一部分数据,HDFS Federation中的多个NameNode共用DataNode。

单个NameNode节点的局限性:

  • 命名空间的限制

NameNode上存储着整个HDFS上的文件的元数据,NameNode是部署在
一台机器上的,因为单个机器硬件的限制,必然会限制NameNode所能管
理的文件个数,制约了数据量的增长。

  • 数据隔离问题

整个HDFS上的文件都由一个NameNode管理,所以一个程序很有可能会
影响到整个HDFS上的程序,并且权限控制比较复杂。

  • 性能瓶颈

单个NameNode时HDFS文件系统的吞吐量受限于单个NameNode的吞吐
量。因为NameNode是个JVM进程,JVM进程所占用的内存很大时,性能
会下降很多。

HDFS联盟架构:
在这里插入图片描述
(5) HDFS HA

单NameNode的缺陷存在单点故障的问题,如果NameNode不可用,则会
导致整个HDFS文件系统不可用。所以需要设计高可用的HDFS(Hadoop
HA)来解决NameNode单点故障的问题。解决的方法是在HDFS集群中设
置多个NameNode节点。但是一旦引入多个NameNode,就有一些问题需
要解决。

HDFS HA需要保证的四个问题:

  • 保证NameNode内存中元数据数据一致,并保证编辑日志文件的安全
    性。

  • 多个NameNode如何协作

  • 客户端如何能正确地访问到可用的那个NameNode。

  • 怎么保证任意时刻只能有一个NameNode处于对外服务状态。

解决方法:

  • 对于保证NameNode元数据的一致性和编辑日志的安全性,采用
    Zookeeper来存储编辑日志文件。

  • 两个NameNode一个是Active状态的,一个是Standby状态的,一个时间
    点只能有一个Active状态的NameNode提供服务,两个NameNode上存储的元数据是实时同步的,当Active的NameNode出现问题时,通过
    Zookeeper实时切换到Standby的NameNode上,并将Standby改为Active
    状态。

  • 客户端通过连接一个Zookeeper的代理来确定当时哪个NameNode处于服
    务状态

HDFS HA架构图:

  • HDFS HA架构中有两台NameNode节点,一台是处于活动状态
    (Active)为客户端提供服务,另外一台处于热备份状态(Standby)

  • 元数据文件有两个文件:fsimage和edits,备份元数据就是备份这两个文
    件。JournalNode用来实时从Active NameNode上拷贝edits文件,
    JournalNode有三台也是为了实现高可用

  • Standby NameNode不对外提供元数据的访问,它从Active NameNode
    上拷贝fsimage文件,从JournalNode上拷贝edits文件,然后负责合并
    fsimage和edits文件,相当于SecondaryNameNode的作用。最终目的是保
    证Standby NameNode上的元数据信息和Active NameNode上的元数据信
    息一致,以实现热备份。

  • Zookeeper来保证在Active NameNode失效时及时将Standby NameNode
    修改为Active状态。

  • ZKFC(失效检测控制)是Hadoop里的一个Zookeeper客户端,在每一
    个NameNode节点上都启动一个ZKFC进程,来监控NameNode的状态,
    并把NameNode的状态信息汇报给Zookeeper集群,其实就是在
    Zookeeper上创建了一个Znode节点,节点里保存了NameNode状态信
    息。当NameNode失效后,ZKFC检测到报告给Zookeeper,Zookeeper把
    对应的Znode删除掉,Standby ZKFC发现没有Active状态的NameNode
    时,就会用shell命令将自己监控的NameNode改为Active状态,并修改
    Znode上的数据。

Znode是个临时的节点,临时节点特征是客户端的连接断了后就会把znode删除,所以当ZKFC失效时,也会导致切换NameNode。

  • DataNode会将心跳信息和Block汇报信息同时发给两台NameNode,DataNode只接受Active NameNode发来的文件读写操作指令。

三、 工作机制

1、副本存放和读取策略

HDFS中的文件是被分成块存放的,为了达到数据的高可用性,每一个块会保存N个副本,如果数据块损坏,就会读取副本来恢复数据块,而副本的存放策略是HDFS可靠性和性能的关键。

举个例子:HDFS默认副本数是3,HDFS存放的策略是将第一个副本存放在本地节点上,第二个副本存放在同一个机架的不同节点上,第三个副本存放在不同机架上另一个节点上,同一个机架上的两个节点同时失效的概率要比一个节点失效的概率低,而两个机架同时失效的概率要比一个机架上两个节点失效的概率低,这样尽最大可能地提高数据存储的可靠性;另外读取副本时,为了减少带宽,首先尝试读取同一个节点上的第一个副本,读取失败后再去读取同一个机架上另外一个节点上的第二个副本,如果还是读取失败,就读取不同机架上的第三个副本,这样尽可能地提高读取副本的性能。

Paste_Image.png

2、机架感知

为了提高HDFS的数据存储可靠性和提高数据读写的性能,HDFS采用了一种称为机架感知的策略:

在一个交换机上的所有节点被称为在一个机架上,通常HDFS运行在跨越多个机架的集群上,通常同一个机架上的两个节点间的带宽比不同机架上的两个节点间的带宽要大。HDFS的机架感知策略就是将一个数据块的副本存放在不同机架上,这样防止整个机架的失效导致数据的丢失,从而提高数据的存储可靠性,同时读取副本时,优先读取同一个机架上的副本,从而提高副本读取的性能。配置dfs.network.script 参数来确定节点所处的机架。当这个脚本配置完毕,每个节点都会运行这个脚本来获取它的机架ID。默认的安装假定所有的节点属于同一个机架。

机架感知设置步骤:

(1) 编写机架感知的脚本

机架感知的脚本是用Python写的,输入一个域名或者IP,返回所在机架。

#!/usr/bin/python
#-*-coding:UTF-8 -*-
import sys

rack = {"hadoop-node-31":"rack1",
        "hadoop-node-32":"rack1",
        "hadoop-node-33":"rack1",
        "hadoop-node-34":"rack1",      
        "192.168.1.50":"rack2",
        "192.168.1.51":"rack2",
        "192.168.1.52":"rack2",
        "192.168.1.53":"rack2",
        "192.168.1.54":"rack2",
       }
if __name__=="__main__":
    print "/" + rack.get(sys.argv[1],"rack0")

(2) 配置脚本路径
将脚本放在NameNode所在的机器上,然后在core-site.xml中配置

<property>
<name>topology.script.file.name</name>
<value>/opt/topology.py</value>
</property>

(3) 重启NameNode,使得机架感知生效。

3、安全模式

NameNode启动后会进入安全模式,安全模式下进行NameNode的初始化操作,不接受客户端的写入操作,只接受读取操作,并且不进行数据块的复制。安全模式下的NameNode做的工作如下:

(1) NameNode从硬盘加载fsimage

NameNode中存存储着fsimage开头、后面带一堆数字的文件,这些是NameNode元数据的序列化后的文件,编号最大的就是最新的文件,NameNode从硬盘读取编号最大的fsimage文件内容,将元数据信息加载到内存里。

(2) 回放edits

edits文件里是存储着还未写入fsimage的操作,尤其是上次NameNode没有正常停止时,为写入fsimage的操作只是写在edits文件里,所以NameNode启动时,加载完fsimage文件后,然后加载edits文件,并且回放edits里的操作,写入fsimage,保证不会丢失操作。

回放edits日志写入fsimage后,NameNode就会创建一个新的fsimage文件和一个空的edits文件。

(3) NameNode等待DataNode报告块信息

fsimage文件里并不记录文件块的信息,文件块的信息存在于DataNode中,所以接下来NameNode需要等待DataNode报告他们各自块的列表信息,DataNode通过心跳机制向NameNode报告。

这里也能看出来,NameNode内存里的元数据的组成结构为:fsimage+edits+datanode中block列表信息;
(4) 退出安全模式

每个数据块都有一个最小副本数,当HDFS中99.9%的块都达到各自的最小副本数时,再等待30秒,就退出安全模式。
这个99.9%可以在hdfs-site.xml中配置,属性名为dfs.namenode.safemode.threshold-pct,默认为0.999f。
这个30秒也是可以在hdfs-site.xml中配置的,属性名为dfs.namenode.safemode.extension,默认是30000。

(5) 复制缺少的副本块

退出安全模式后,检测哪些数据块还没有达到最小副本数,从其他副本块中复制数据块进行补充。

(6) 流程图

这里写图片描述

4、HDFS程序文件结构

(1) HDFS数据存储配置

${HADOOP_HOME}/etc/hadoop/core-site.xml配置文件中的hadoop.tmp.dir属性用来配置HDFS文件存储的目录路径,NameNode节点和DataNode节点都是读取这个属性。

  • NameNode存储路径配置属性为:dfs.namenode.name.dir,默认为:file://${hadoop.tmp.dir}/dfs/name

  • DataNode存储路径配置属性为:dfs.datanode.data.dir,默认为:file://${hadoop.tmp.dir}/dfs/data
    比如hadoop.tmp.dir属性设置的是:/opt/data/tmp,下面来介绍下各自文件。

(2) NameNode节点文件

[hadoop@bigdata-senior01 tmp]$ ll /opt/data/tmp/dfs/name/current/

Paste_Image.png

NameNode中有几类文件:

  • fsimage文件:

NameNode在运行状态时,元数据是存储在内存里的,这样能保证数据的读写速度很快,但是NameNode会将元数据信息存储在硬盘里,fsimage文件就是存储元数据的映像文件,fsimage文件名称后面的编码最大的文件,就是当前正在使用的fsimage文件。

  • fsimage_*****.md5文件

是校验文件,用于验证fsimage的完整性。

  • edits文件

edits文件是NameNode元数据日志文件,当有元数据的写入需求时,先将日志写入edits文件,因为edits文件比fsimage文件要小很多,所以写入非常快。之后SencondaryNameNode会协助将edits日志写入fsimage文件。

  • seen_txid文件

seen_txid文件中的数字是当前正在使用的edits文件的编号,namenode启动时用来判断回放seen_txid指定版本的日志。

  • VERSION文件

[hadoop@bigdata-senior01 tmp]$ cat /opt/data/tmp/dfs/name/current/VERSION
#Tue Jul 05 09:00:19 CST 2016
namespaceID=2101579007
clusterID=CID-205277e6-493b-4601-8e33-c09d1d23ece4
cTime=0
storageType=NAME_NODE
blockpoolID=BP-1641019026-127.0.0.1-1467624350057
layoutVersion=-57

  • namespaceID是HDFS文件系统的唯一标示,在格式化的时候生成。

  • clusterID是集群ID,NameNode和DataNode的集群ID应该一致,格式化的时候可以指定一个集群ID,没有指定则会自动生成一个集群ID。

  • cTime是NameNode的Fsimage的创建时间,如果layoutVersion发生变化触发一次升级,就会更新。

  • storageType是说明这个文件存储的是什么进程的数据结构信息,NAME_NODE或者DATA_NODE。

  • blockpoolID是存储块池的Id。

  • layoutVersion表示 HDFS 永久性数据结构的版本信息, 只要数据结构变更,版本号也要递减,此时的 HDFS 也需要升级,否则磁盘仍旧是使用旧版本的数据结构,这会导致新版本的 NameNode 无法使用。

(3) DataNode节点文件

[hadoop@bigdata-senior01 tmp]$ ll /opt/data/tmp/dfs/data/current/BP-1641019026-127.0.0.1-1467624350057/current/finalized/

Paste_Image.png

blk_开头的文件是块文件。

5、数据读取流程

Paste_Image.png

(1) HDFS客户端调用DistributedFileSystem类的open()方法,通过RPC协议请求NameNode来确定所请求的文件所在位置,找出最近的DataNode节点的地址。

(2) DistributedFileSystem会返回一个FSDataInputStream输入流对象给客户端。

(3) 客户端会在FSDatatInputStream上调用read()函数,按照每个DataNode的距离从近到远依次读取。

(4) 读取完每个DataNode后,在FSDataInputStream上调用close()函数。

(5) 如果读取出现故障,就会读取数据块的副本,同时向NameNode报告这个消息。

6、数据写入流程

Paste_Image.png

(1) 客户端调用DistributedFileSystem对象的create()方法,通过RPC协议调用NameNode,在命名空间创建一个新文件,此时还没有关联的DataNode与之关联。

(2) create()方法会返回一个FSDataOutputStream对象给客户端用来写入数据。

(3) 写入数据前,会将文件分割成包,放入一个“数据队列”中。

(4) NameNode为文件包分配合适的DateNode存放副本,返回一个DataNode的管道。

(5) 根据管道依次保存文件包在各个DataNode上。

(6) 各个DataNode保存好文件包后,会返回确认信息,确认消息保存在确认队列里,当管道中所有的DataNode都返回成功的的确认信息后,就会从确认队列里删除。

管道中所有的DataNode都保存完成后,调用FileSystem对象的close()关闭数据流。


这一篇博文是【大数据技术●降龙十八掌】系列文章的其中一篇,点击查看目录:这里写图片描述大数据技术●降龙十八掌

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. HIVE结构 Hive 是建立在 Hadoop 上的数据仓库基础构架。它提供了一系列的工具,可以用来进行数 据提取转化加载 (ETL),这是一种可以存储、 查询和分析存储在 Hadoop 中的大规模数据的 机制。 Hive 定义了简单的类 SQL 查询语言,称为 QL,它允许熟悉 SQL 的用户查询数据。 同时,这个语言也允许熟悉 MapReduce 开发者的开发自定义的 mapper 和 reducer 来处理 内建的 mapper 和 reducer 无法完成的复杂的分析工作。 1.1HIVE 架构 Hive 的结构可以分为以下几部分: 用户接口:包括 CLI, Client, WUI 元数据存储。通常是存储在关系数据库如 mysql, derby 中 6 解释器、编译器、优化器、执行器 Hadoop:用 HDFS 进行存储,利用 MapReduce 进行计算 1、 用户接口主要有三个: CLI,Client 和 WUI。其中最常用的是 CLI , Cli 启动的时候, 会同时启动一个 Hive 副本。 Client 是 Hive 的客户端,用户连接至 Hive Server 。 在启动 Client 模式的时候, 需要指出 Hive Server 所在节点,并且在该节点启动 Hive Server 。 WUI 是通过浏览器访问 Hive 。 2、 Hive 将元数据存储在数据库中,如 mysql 、 derby 。 Hive 中的元数据包括表的名字, 表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。 3、 解释器、编译器、优化器完成 HQL 查询语句从词法分析、语法分析、编译、优化以及 查询计划的生成。生成的查询计划存储在 HDFS 中,并在随后有 MapReduce 调用执行。 4、 Hive 的数据存储在 HDFS 中,大部分的查询由 MapReduce 完成(包含 * 的查询,比 如 select * from tbl 不会生成 MapRedcue 任务)。 1.2Hive 和 Hadoop 关系 Hive 构建在 Hadoop 之上, HQL 中对查询语句的解释、优化、生成查询计划是由 Hive 完成的 所有的数据都是存储在 Hadoop 中 查询计划被转化为 MapReduce 任务,在 Hadoop 中执行(有些查询没有 MR 任 务,如: select * from table ) Hadoop和 Hive 都是用 UTF-8 编码的 7 1.3Hive 和普通关系数据库的异同 Hive RDBMS 查询语言 HQL SQL 数据存储 HDFS Raw Device or Local FS 索引 无 有 执行 MapReduce Excutor 执行延迟 高 低 处理数据规模 大 小 1. 查询语言。由于 SQL 被广泛的应用在数据仓库中,因此,专门针对 Hive 的特性设计 了类 SQL 的查询语言 HQL。熟悉 SQL 开发的开发者可以很方便的使用 Hive 进行开 发。 2. 数据存储位置。 Hive 是建立在 Hadoop 之上的,所有 Hive 的数据都是存储在 HDFS 中 的。而数据库则可以将数据保存在块设备或者本地文件系统中。 3. 数据格式。 Hive 中没有定义专门的数据格式,数据格式可以由用户指定,用户定义数 据格式需要指定三个属性:列分隔符(通常为空格、” t ”、” x001″)、行分隔符 (” n”)以及读取文件数据的方法( Hive 中默认有三个文件格式 TextFile , SequenceFile 以及 RCFile )。由于在加载数据的过程中,不需要从用户数据格式到 Hive 定义的数据格式的转换,因此, Hive 在加载的过程中不会对数据本身进行任何修 改,而只是将数据内容复制或者移动到相应的 HDFS 目录中。而在数据库中,不同的数 据库有不同的存储引擎,定义了自己的数据格式。所有数据都会按照一定的组织存储, 因此,数据库加载数据的过程会比较耗时。 4. 数据更新。由于 Hive 是针对数据仓库应用设计的,而数据仓库的内容是读多写少的。 因此, Hive 中不支持对数据的改写和添加,所有的数据都是在加载的时候中确定好的。 而数据库中的数据通常是需要经常进行修改的,因此可以使用 INSERT INTO ... VALUES 添加数据,使用 UPDATE ... SET 修改数据。 5. 索引。之前已经说过, Hive 在加载数据的过程中不会对数据进行任何处理,甚至不会 对数据进行扫描,因此也没有对数据中的某些 Key 建立索引。 Hive 要访问数据中满足 条件的特定值时,需要暴力扫描整个数据,因此访问延迟较高。由于 MapReduce 的引 入, Hive 可以并行访问数据,因此即使没有索引,对于大数据量的访问, Hive 仍然 可以体现出优势。数据库中,通常会针对一个或者几个列建立索引,因此对于少量的特 定条件的数据的访问,数据库可以有很高的效率,较低的延迟。由于数据的访问延迟较 高,决定了 Hive 不适合在线数据查询。 6. 执行。 Hive 中大多数查询的执行是通过 Hadoop 提供的 MapReduce 来实现的(类似 select * from tbl 的查询不需要 MapReduce)。而数据库通常有自己的执行引擎。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值