HDFS Architecture

Introduction

HDFS(Hadoop Distributed File System)是一个分布式文件系统,它具备很高的容错性,能够支持运行在廉价的硬件设备上。HDFS具备很高的吞吐量,很是适合拥有海量数据的application。HDFS放宽了一些POSIX要求,以支持的方式访问文件系统中的数据。HDFS是Apache Hadoop核心项目的一部分。html

HDFS设计目标

  • 硬件故障是常常会发生的

一个HDFS实例能够包含成百上千台的服务器,每一个服务器存储整个文件系统数据的一部分。每台服务器都有必定的几率出现硬件故障,这意味着一个HDFS实例中的一部分服务器在某个时刻多是不可用的。所以,发现故障并可以从故障中快速恢复是HDFS的核心目标。node

  • 批处理

HDFS适合应用在批处理领域,而不适合与用户交互的领域。它的设计目标是数据访问的高吞吐量,而不是低延迟。服务器

  • 大数据集

运行在HDFS上的application一般都拥有大数据集,例如一个文件能够达到gigabytes或terabytes大小。所以一个HDFS集群能够扩展到数百个节点,能够支持数千万个文件的存储。网络

  • 简单的一致性模型

HDFS上的文件模型是write-once-read-many。一个文件在完成建立-写入数据-关闭后只能再对文件执行appends和truncates两种类型修改操做,没法再执行其它形式的修改。即只能在文件尾部添加或删除数据,不支持在文件的任意位置修改数据。数据结构

  • 使计算节点靠近它须要的数据

在分布式系统中,若是一个计算节点要处理的数据离本身很近,那么会有助于提升数据计算的效率。要处理的数据量越大,则效率的提高越明显。由于这会下降整个系统的网络拥塞,并提升分布式系统总体的吞吐量。HDFS提供了相应的API,能够将application自己移向数据存储的节点。架构

NameNode and DataNodes

HDFS采用master/slave架构,集群中master的角色由NameNode扮演,slave的角色由DataNode扮演。
一个HDFS集群中只包含一个NameNode节点,它负责管理整个文件系统的命名空间(namespace),并对访问文件的client进行权限控制。此外,一个集群包含有多个DataNode节点,一般集群中的每一个服务器上都运行一个DataNode程序,DataNode负责管理它所在服务器节点的存储空间。
HDFS对外暴露一个统一的文件系统命名空间并容许用户数据存储在文件中。在HDFS内部,一个文件会被拆分红一个或多个block,这些block会被存储到一组DataNodes中。
NameNode会负责执行文件系统的一系列操做,如open、close、对文件或目录rename等。此外,NameNode还会负责在文件block和DataNode间创建mapping关系。
DataNode会负责对从client发起的文件系统读写请求提供服务。DataNode还会负责文件block的建立和删除,并根据NameNode的指示建立文件block的多副本。
NameNode和DataNode均可以运行在廉价的硬件设备上,这些硬件设备一般会安装Linux操做系统。HDFS是由Java语言开发的,因此任何支持Java的平台都可以运行NameNode和DataNode程序。一个HDFS集群典型的部署方式是用一台专门的服务器部署NameNode,再在集群中的其它服务器各运行一个DataNode。也能够在一个服务器上部署多个DataNode,但这种部署方式并不常见。
整个集群只有一个NameNode节点大大简化了HDFS系统的架构——NameNode负责管理整个文件系统的元数据(metadata)。在这种架构下,用户数据只由DataNode处理,永远不会流经NameNode节点。
图片描述并发

The File System Namespace

HDFS支持传统层级结构的文件组织方式(相似Linux文件结构),用户能够建立目录结构并用于存储文件。用户能够在HDFS建立、删除文件,将文件从一个目录转移到另外一个目录,对文件重命名等,此外还支持文件权限控制。HDFS不支持hard link和soft link,但在将来不排除实现这个特性的可能。
NameNode负责维护整个文件系统的namespace,任何对文件系统namespace的修改都会被记录到NameNode中。例如,application能够指定一个文件在HDFS中存储的副本数量,这个副本数量叫作这个文件的副本因子(replication factor),这个信息就是存储在NameNode中。app

Data Replication

HDFS的设计目标是可以跨集群中多个服务器可靠存储很是大的文件,它将文件切分红一系列的block进行存储。为了实现容错性,每一个文件block都会存储多个副本。每一个文件的block大小和其副本因子都是能够配置的,一个文件的全部block大小都相同(除了最后一个block)。application能够指定文件副本的数量,副本因子既能够在文件建立时指定,也能够在文件建立好后修改。HDFS中的文件都只能被写一次(除了appends和truncates),而且在任什么时候刻都只能有一个writer在执行写操做(不支持并发写操做)。
NameNode负责管理全部的文件block replication,它会周期的收到集群中的DataNode发送的心跳和Block report。收到心跳意味着DataNode工做正常,Blockreport则包含DataNode上全部block的列表。
图片描述分布式

The Persistence of File System Metadata

在NameNode服务器上有一个普通文件叫作FsImage,它存储了整个文件系统的namespace,包括blocks和文件的mapping,文件系统的其它属性等也都被存储在这个文件中。NameNode会将FsImage文件内容保存到内存中,以提升文件系统元数据的效率。虽然这样读取FsImage中的元数据会很高效,但若是每次文件系统元数据被修改就直接修改FsImage文件中的内容,效率会很是的差。
因此NameNode引入了Editlog机制,它利用一个被称做Editlog的事务日志持久化记录文件系统元数据的每次变化。例如,当在HDFS中建立一个新的文件时,NameNode将会在EditLog中insert一条新的记录标识此次变化。一样的,修改一个文件的副本因子也会向Editlog中insert一条新的记录。NameNode会借助它所在服务器上操做系统的文件系统存储Editlog,Editlog只是增量的记录每一个对文件系统元数据的操做。
Editlog中存储的只是对文件系统元数据修改的操做,这些操做的结果总归要反应到FsImage中的数据变化才行。因此每隔一段时间,NameNode会结合Editlog和当前的FsImage生成一个新版本的FsImage,新版本的FsImage中包含了Editlog中记录的操做对文件系统对元数据的修改。新版本的FsImage生成好以后,Editlog记录的操做日志就能够被删除了。这个过程被称做checkpoint
checkpoint的执行能够经过配置指定。dfs.namenode.checkpoint.period配置指定通过多长时间执行一次checkpoint,单位时间是秒。dfs.namenode.checkpoint.txns配置执行通过多少次事务操做触发一次checkpoint。若是同时配置了这两个选项,那么哪一个先知足条件,哪一个就会触发checkpoint。
在NameNode刚启动或者checkpoint期间,NameNode会执行从磁盘将FsImage文件的内容刷新到内存的操做。
DataNode并不知道文件的概念,在它眼中只有block,它存储的只是一个一个block数据。oop

Robustness

HDFS的主要目标就是即便在有硬件错误的状况下,也要可以可靠的存储数据。可能发生的错误主要有三种,分别是NameNode服务器出错,DataNode服务器出错,网络异常引起脑裂。

  • 应对DataNode服务器异常,心跳机制和多副本数据

每一个DataNode都会周期性的向NameNode发送心跳message。若是网络异常致使整个网络被割裂,将会致使有一部分DataNode与NameNode的链接断开。NameNode能够根据心跳message判断与DataNode的链接情况,若是一段时间内都没有收到DataNode的心跳message,那么NameNode会把那个DataNode标记为dead,而且再也不向被标记为dead的DataNodes转发任何IO请求。被标记为dead的DataNodes上的全部数据对整个HDFS系统都是不可用的。
DataNode死亡可能会致使某些文件block的副本数量低于副本因子指定的副本数量,这就须要从新增长这些文件block的副本数量,使其恢复到原来指定的值。NameNode会持续跟踪这些须要增长副本数量的文件block并为其增长新的副本。
有下面几种状况,NameNode会为文件block增长新的副本:
a. DataNode节点故障,致使在其上的全部文件block副本均不可用
b. DataNode服务器上的磁盘故障,致使该磁盘上的全部文件block所有不可用
c. 从新对一个文件的副本因子进行设置使其增大,表示须要更多的副本
将一个DataNode标记为dead是很谨慎的,默认状况下是NameNode在10分钟内收不到一个DataNode的心跳message,才会将这个DataNode标记为dead。固然你能够将这个时间设置的更短。

  • Cluster Rebalancing

HDFS能够对数据的存储位置作调整使数据在整个集群中的存储“重平衡”,即将数据从一个DataNode节点移动到另外一个DataNode节点。但目前“重平衡”机制尚未被实现。

  • Data Integrity

从DataNode获取的数据有多是错误的,这种数据错误可能由存储硬件、网络错误和软件bug等多种缘由致使。HDFS客户端实现了对文件内容的checksum检查机制。当客户端在HDFS上建立一个文件时,它会对这个文件的每一个block都计算一个checksum,并将这些checksums分别保存在HDFS上的隐藏文件中。当客户端接收文件内容时,它会验证从DataNode发来的数据是否和存储在隐藏文件中的checksum值匹配。若是不匹配,客户端将选择从另外一个DataNode节点获取那个block的副本。

  • Metadata Disk Failure

FsImage和EditLog是HDFS系统的核心数据结构,若是它们出现一点问题,那么将会致使整个HDFS实例不可用。为了防止FsImage和EditLog数据被破坏,能够配置NameNode存储FsImage和EditLog两种数据的多份copy,任何FsImage和EditLog的修改操做都会触发对全部copy的同步更新。这种同步更新所有copy的机制会致使NameNode的TPS降低,可是元数据的TPS降低是能够接受的,由于HDFS应用通常都是读多写少,并不会对元数据作频繁的修改。
另外一种加强NameNode的抗挫机制是增长多个NameNode节点,这点会在后面在讨论。

  • Snapshots

能够在某个时刻存储HDFS整个系统的一个copy,这种机制能够支持在HDFS数据被破坏时rollback到以前的一个good point。

Data Organization

  • Data Blocks

一般状况下,HDFS中的一个文件block大小为128MB。HDFS中的一个文件会被切割成多个128MB的block存储。若是条件容许,一个文件的每一个block会被分散到不一样的DataNode节点存储。

  • Replication Pipelining

客户端向HDFS写入数据,假设副本因子是3。首先客户端会先访问NameNode节点,NameNode会根据replication target choosing algorithm从全部DataNodes中选出3个,并向客户端返回由这3个DataNode组成的列表。被选中的这3个DataNode将用来存储block的3个副本。
接着,客户端会向第一个DataNode写入数据,写入数据的方式是分批(portion)进行的,写完block的一批(一部分)数据后,再写下一批数据。第一个DataNode节点接收到一批数据后,会将接收到的数据保存在本身本地的存储,而后将数据转发给列表中第二个DataNode节点。第二个DataNode节点接收到数据后,也会将数据保存到本身本地存储,而后将数据转发给列表中第三个DataNode节点。第三个节点接收到数据,将数据写入到本身的本地存储,至此一批数据算是写入完成。
这三个DataNode构成了一条流水线,一个DataNode会从它前面的DataNode获取数据,并将收到的数据转发给它后面的DataNode。就这样,数据沿着这条流水线从第一个DataNode转发到最后一个DataNode。
详细了解HDFS写入数据流程,能够参考这个漫画

The Communication Protocols

HDFS的通讯协议是创建在TCP/IP协议之上的。NameNode不会主动发起链接请求,它只有对请求作出响应。

相关文章
相关标签/搜索