1. 设计初衷
分而治之:将大文件、大批量文件,分布式存放在大量服务器上,以便于采取分而治之的方式对海量数据进行运算分析。
2. 优缺点
2.1 优点
- 高容错性
1)数据自动保存多个副本。它通过增加副本的形式,提高容错性
2)某一个副本丢失以后,它可以自动恢复,这是由 HDFS 内部机制实现的,我们不必关心。 - 适合批处理
1)它是通过移动计算而不是移动数据
2)它会把数据位置暴露给计算框架。 - 适合大数据处理
1)处理数据达到 GB、TB、甚至PB级别的数据。
2)能够处理百万规模以上的文件数量,数量相当之大。
3)能够处理10K节点的规模 - 流式文件访问
1)一次写入,多次读取。文件一旦写入不能修改,只能追加。
2)它能保证数据的一致性。 - 可构建在廉价机器上
1)它通过多副本机制,提高可靠性。
2)它提供了容错和恢复机制。比如某一个副本丢失,可以通过其它副本来恢复。
2.2 缺点
- 低延时数据访问
1)比如毫秒级的来存储数据,这是不行的,它做不到。
2)它适合高吞吐率的场景,就是在某一时间内写入大量的数据。但是它在低延时的情况下是不行的,比如毫秒级以内读取数据,这样它是很难做到的。 - 小文件存储
1)存储大量小文件的话,它会占用 NameNode大量的内存来存储文件、目录和块信息。这样是不可取的,因为NameNode的内存总是有限的。
2)小文件存储的寻道时间会超过读取时间,它违反了HDFS的设计目标。 - 并发写入、文件随机修改
1)一个文件只能有一个写,不允许多个线程同时写。
2)仅支持数据 append(追加),不支持文件的随机修改。
3. HDFS体系架构
3.1 体系架构
HDFS主要有以下组件组成:
- Client客户端
- NameNode管理者
- DataNode数据节点
- SecondaryNameNode节点,辅助NameNode完成一些工作
3.2 Client客户端
客户端是用户和HDFS进行交互的手段,HDFS提供了各种各样的客户端,包括命令行接口、Java API, Thrift接口、C语言库、用户空间文件系统〔Filesystem in Userspace,FUSE)等
主要工作内容:
- 文件切分。文件上传 HDFS 的时候,Client 将文件切分成 一个一个的Block,然后进行存储。
- 与 NameNode 交互,获取文件的位置信息。
- 与 DataNode 交互,读取或者写入数据。
- Client 提供一些命令来管理 HDFS,比如启动或者关闭HDFS。
- Client 可以通过一些命令来访问 HDFS。
3.3 NameNode管理节点
NameNode就是HDFS的Master架构,主要负责HDFS文件系统的管理工作,具体包括名称空间(namespace)管理,文件Block管理。
- 名称空间(namespace)管理:它维护着文件系统树(filesystem tree)以及文件树中所有的文件和文件夹的元数据(metadata)。管理这些信息的文件有两个,分别是Namespace 镜像文件(fsimage)和操作日志文件(edit log),这些信息被Cache在RAM中以及持久化存储在本地硬盘。
fsimage:metadata存储到磁盘中的镜像文件
editlog:记录对medadata的操作日志 - 文件Block管理:Namenode记录着每个文件中各个块所在的数据节点的位置信息(元数据信息),从NameNode中你可以获得每个文件的每个块所在的DataNode。但是他并不持久化存储这些信息,因为这些信息NameNode会在每次启动系统时动态地重建这些信息。
元数据信息,包括:
1)文件owership和permissions
2)文件包含哪些Block
3)Block保存在哪个DataNode(由DataNode启动时上报) - 接收客户端读写请求
- 配置副本策略
3.4 DataNode数据节点
3.4.1 功能
- 存储数据:一个数 据块Block会在多个DataNode中进行冗余备份;而一个DataNode对于一个块最多只包含一个备份。所以可以简单地认为DataNode上存储了数据块ID和数据块内容,以及它们的映射关系。
- 启动DN线程的时候会向NN汇报block信息
- 通过心跳定时和NameNode进行通信发送所存储的文件块信息(3秒一次),并在心跳通信应答中接受NameNode的指令,如删除数据库或者把数据块复制到另一个DataNode(如果NN 10分钟没有收到DN的心跳,则认为其已经lost,并copy其上的block到其他DN)
- 作为服务器接受来自客户端的访问,处理数据块读/写请求(DataNode之间还会相互通信,执行数据块复制任务,同时,在客户端执行写操作的时候,DataNode之间需要相互配合,以保证写操作的一致性)
3.4.2 数据块block
3.4.2.1 block配置
HDFS中的文件在物理上是分块存储(block),块的大小可以通过配置参数( dfs.blocksize)来规定,默认大小在hadoop2.x版本中是128M,老版本中是64M
3.4.2.2 文件读取时间
文件查找时间主要分为两个阶段:磁盘寻址开销时间和磁盘传输时间
- 为了最小化磁盘寻址时间,会设置block的物理块大于磁盘块大小,如果块设置得足够大,从磁盘传输数据的时间会明显大于定位这个块开始位置所需的时间。因而,传输一个由多个块组成的文件的时间取决于磁盘传输速率。
- 如果寻址时间(找到物理位置)约为10ms,而传输速率为100MB/s,为了使寻址时间仅占传输时间的1%(最佳状态),我们要将块大小设置约为100MB。默认的块大小实际为64MB,但是很多情况下HDFS使用128MB的块设置。
块的大小:10ms100100M/s = 100M
3.1.3 block副本
HDFS中为了保证数据高可用性及容错性,会另外存储block的副本文件到其他节点上
- 副本数设置
在dfs-site.xml里设置
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
比如这里设置成3个副本数,这时候就会按照以下机架策略进行分配节点数据
-
机架存储策略
若存在多个机架,副本存储策略如下:
1)本机架A一个数据节点存储一份
2)另外一个机架B挑选一个数据节点存储一份
3)最后一份仍在机架B上挑选不同的数据节点进行存储
3.5 SecondNameNode
主要是定时对NameNode的数据snapshots进行备份,这样可尽量降低NameNode崩溃之后导致数据丢失的风险。
主要工作内容:
- 从NameNode获得fsimage和edits后把两者重新合并发给NameNode,这样可以减轻NameNode的工作负担,又可以安全的进行备份(通常SecondNameNode会单独部署在新的物理机上)
- 一旦NameNode挂掉,SecondeNameNode会辅助进行数据恢复(但由于SNN上的数据同步会有一定的延迟,不可避免的会存在一些数据丢失的情况,所以目前更多采用的是NameNode HA的集群部署方式)
3.5.1 目录结构
- NameNode目录结构
${dfs.name.dir}/current
................................./VERSION
................................./edits
................................./fsimage
................................./fstime - SecondNameNode目录结构
${fs.checkpoint.dir}/current
...................................../VERSION
...................................../edits
...................................../fsimage
...................................../fstime
............................./previous.checkpoint
...................................../VERSION
...................................../edits
...................................../fsimage
...................................../fstime
5.3.2 工作原理
概念:
edit log:当客户端执行写操作,则NameNode会在edit log记录下来,并在内存中保存一份文件系统的元数据。
fsimage:是文件系统元数据的持久化检查点,不会在写操作后马上更新,因为fsimage写非常慢
目的:
由于Edit log不断增长,在NameNode重启时,会造成长时间NameNode处于安全模式,不可用状态,是非常不符合Hadoop的设计初衷。所以要周期性合并Edit log,但是这个工作由NameNode来完成,会占用大量资源,这样就出现了Secondary NameNode,它可以进行image检查点的处理工作。
工作步骤:
- Secondary NameNode请求NameNode进行edit log的滚动(即创建一个新的edit log),将新的编辑操作记录到新生成的edit log文件;
- 通过http get方式,读取NameNode上的fsimage和edits文件,到Secondary NameNode上;
- 读取fsimage到内存中,即加载fsimage到内存,然后执行edits中所有操作,并生成一个新的fsimage文件,即这个检查点被创建;
- 通过http post方式,将新的fsimage文件传送到NameNode;
- NameNode使用新的fsimage替换原来的fsimage文件,让(1)创建的edits替代原来的edits文件;并且更新fsimage文件的检查点时间。