编辑推荐: |
本文来自csdn,从HDFS的背景、基本概念
开始,步步深入了解HDFS的设计目标、HDFS的基本结构以及HDFS的相关操作等核心知识。 |
|
HDFS核心技术详解
我们都知道Hadoop 主要由HDFS和MapReduce 两个核心部分组成。其中最底部就是HDFS,它被用来存储Hadoop集群中所有存储节点上的文件。
hadoop的核心子项目——HDFS(分布式文件系统),下面将从HDFS的背景、基本概念
开始,步步深入了解HDFS的设计目标、HDFS的基本结构以及HDFS的相关操作等核心知识!
(一)HDFS 的产生背景?
随着数据量越来越大,在一个操作系统管辖的范围内存不下了,那么就分配到更多的操 作系统管理的磁盘中,但是不方便管理和维护,迫切需要一种系统来管理多台机器上的文
件,这就是分布式文件管理系统。HDFS只是分布式文件管理系统中的一种。
(二)HDFS 到底是什么?
HDFS(HadoopDistributedFileSystem)是Hadoop的核心子项目,是一个可以运行在普通硬件设备上的分布式文件系统,是分布式计算中数据存储和管理的基础,是基于流
数据模式访问和处理超大文件的需求而开发的。它所具有的高容错、高可靠性、高可扩展性、高吞吐率等特征为海量数据提供了不怕故障的存储,给超大数据集(LargeDataSet)
的应用处理带来了很多便利。
(三)HDFS 从何而来?
HDFS源于 Google在2003年10月份发表的GFS(Google File System)论文。
它其实就是 GFS的一个克隆版本。
(四)HDFS的设计目标
1、硬件故障是常态,而不是异常
2、适合流式数据访问
3、适合大规模数据集
4、简单的一致性模型
5、移动计算比移动数据更划算
6、轻便的访问异构的软硬件平台
(五)HDFS的架构和数据存储原理
HDFS是一个主/从(Mater/Slave)体系结构,从最终用户的角度来看,它就像传统的 文件系统一样,可以通过目录路径对文件执行CRUD(Create、Read、Update和Delete)
操作。但由于分布式存储的性质,HDFS集群拥有一个NameNode和一些DataNode。
NameNode管理文件系统的元数据,DataNode存储实际的数据。客户端通过同
NameNode和DataNodes的交互访问文件系统。客户端联系NameNode以获取文件的元数
据,而真正的文件I/O操作是直接和DataNode进行交互的。
HDFS的架构图
这种架构主要由四个部分组成,分别为HDFS Client、NameNode、DataNode和Secondary
NameNode。下面我们分别介绍这四个组成部分。
Client:就是客户端。
1、文件切分。文件上传 HDFS的时候,Client将文件切分成 一个一个的Block,然后进行存储。
2、与 NameNode 交互,获取文件的位置信息。
3、与 DataNode 交互,读取或者写入数据。
4、Client 提供一些命令来管理 HDFS,比如启动或者关闭HDFS。
5、Client 可以通过一些命令来访问 HDFS。
NameNode:就是 master,它是一个主管、管理者。
1、管理 HDFS 的名称空间。
2、管理数据块(Block)映射信息
3、配置副本策略
4、处理客户端读写请求。
DataNode:就是Slave。NameNode 下达命令,DataNode 执行实际的操作。
1、存储实际的数据块。
2、执行数据块的读/写操作。
Secondary NameNode:并非 NameNode 的热备。当NameNode 挂掉的时候,它并不能马上替换
NameNode 并提供服务。
1、辅助 NameNode,分担其工作量。
2、定期合并 fsimage和fsedits,并推送给NameNode。
3、在紧急情况下,可辅助恢复 NameNode。
(六)为什么选择 HDFS 存储数据?
1、之所以选择 HDFS 存储数据,是因为 HDFS 具有以下优点:
(1)高容错性
1)数据自动保存多个副本。它通过增加副本的形式,提高容错性。
2)某一个副本丢失以后,它可以自动恢复,这是由 HDFS内部机制实现的,我们不必关
心。
(2)适合批处理
1)它是通过移动计算而不是移动数据。
2)它会把数据位置暴露给计算框架。
(3)适合大数据处理
1)数据规模:能够处理数据规模达到 GB、TB、甚至PB级别的数据。
2)文件规模:能够处理百万规模以上的文件数量,数量相当之大。
3)节点规模:能够处理10K节点的规模。
(4)流式数据访问
1)一次写入,多次读取,不能修改,只能追加。
2)它能保证数据的一致性。
(5)可构建在廉价机器上
1)它通过多副本机制,提高可靠性。
2)它提供了容错和恢复机制。比如某一个副本丢失,可以通过其它副本来恢复。
2、当然 HDFS 也有它的劣势,并不适合所有的场合:
(1)不适合低延时数据访问
1)比如毫秒级的来存储数据,这是不行的,它做不到。
2)它适合高吞吐率的场景,就是在某一时间内写入大量的数据。但是它在低延时的情况 下是不行的,比如毫秒级以内读取数据,这样它是很难做到的。
改进策略
(2)无法高效的对大量小文件进行存储
1)存储大量小文件的话,它会占用 NameNode大量的内存来存储文件、目录和块信息。这样是不可取的,因为NameNode的内存总是有限的。
2)小文件存储的寻道时间会超过读取时间,它违反了HDFS的设计目标。 改进策略
(3)并发写入、文件随机修改
1)一个文件只能有一个写,不允许多个线程同时写。
2)仅支持数据 append(追加),不支持文件的随机修改。
(七)HDFS 如何读取文件?
HDFS的文件读取原理,主要包括以下几个步骤:
1、首先调用FileSystem对象的open方法,其实获取的是一个DistributedFileSystem的
实例。
2、DistributedFileSystem通过RPC(远程过程调用)获得文件的第一批block的
locations,同一block按照重复数会返回多个locations,这些locations按照hadoop拓
扑结构排序,距离客户端近的排在前面。
3、前两步会返回一个FSDataInputStream对象,该对象会被封装成 DFSInputStream
对象,DFSInputStream可以方便的管理datanode和namenode数据流。客户端调用
read方 法,DFSInputStream就会找出离客户端最近的datanode并连接datanode。
4、数据从datanode源源不断的流向客户端。
5、如果第一个block块的数据读完了,就会关闭指向第一个block块的datanode连接,
接着读取下一个block块。这些操作对客户端来说是透明的,从客户端的角度来看只是 读一个持续不断的流。
6、如果第一批block都读完了,DFSInputStream就会去namenode拿下一批blocks的
location,然后继续读,如果所有的block块都读完,这时就会关闭掉所有的流。
(八)HDFS 如何写入文件?
HDFS的文件写入原理,主要包括以下几个步骤:
1.客户端通过调用 DistributedFileSystem 的create方法,创建一个新的文件。
2.DistributedFileSystem通过 RPC(远程过程调用)调用 NameNode,去创建一个没有blocks关联的新文件。创建前,NameNode
会做各种校验,比如文件是否存在, 客户端有无权限去创建等。如果校验通过,NameNode 就会记录下新文件,否则就会抛出IO异常。
3.前两步结束后会返回 FSDataOutputStream 的对象,和读文件的时候相似,
FSDataOutputStream 被封装成 DFSOutputStream,DFSOutputStream
可以协调
NameNode和 DataNode。客户端开始写数据到
DFSOutputStream,DFSOutputStream会把数据切成一个个小packet,然后排成队列data
queue。
4.DataStreamer会去处理接受 data queue,它先问询 NameNode这个新的
block 最适合存储的在哪几个DataNode里,比如重复数是3,那么就找到3个最适合的
DataNode,把它们排成一个 pipeline。DataStreamer把 packet按队列输出到管道的第一个
DataNode中,第一个 DataNode又把 packet输出到第二个 DataNode 中,以此类推。
5.DFSOutputStream 还有一个队列叫 ack queue,也是由 packet 组成,等待
DataNode的收到响应,当pipeline中的所有DataNode都表示已经收到的时候,这时akc
queue才会把对应的packet包移除掉。
6.客户端完成写数据后,调用close方法关闭写入流。
7.DataStreamer 把剩余的包都刷到 pipeline 里,然后等待 ack 信息,收到最后一个
ack 后,通知 DataNode 把文件标示为已完成。
(九)HDFS 副本存放策略
namenode 如何选择在哪个 datanode 存储副本(replication)?这里需要对可靠
性、写入带宽和读取带宽进行权衡。 Hadoop对 datanode存储副本有自己的副本策略,在其发展过程中一共有两个版本的副本策略,分别如下所示。
Hadoop 0.17之前的副本策略
第一个副本:存储在同机架的不同节点上。
第二个副本:存储在同机架的另外一个节点上。第三个副本:存储在不同机架的另外一个节点。其它副本:选择随机存储。
Hadoop 0.17 之后的副本策略
第一个副本:存储在同 Client 相同节点上。第二个副本:存储在不同机架的节点上。
第三个副本:存储在第二个副本机架中的另外一个节点上。其它副本:选择随机存储。
(十)HDFS的新特性HA
(一)HDFS的HA机制
Hadoop2.2.0 版本之前,NameNode是HDFS集群的单点故障点,每一个集群只有一个NameNode,如果这个机器或者进程不可用,整个集群就无法使用,直到重启
NameNode或者新重启一个NameNode节点 。影响HDFS集群不可用主要包括以下两种情况。
(1)类似机器跌宕这样的意外情况将导致集群不可用,只有重启NameNode之后才可使用。
(2)计划内的软件或硬件升级(NameNode节点)将导致集群在短时间范围内不可用。
HDFS的高可用性(HA,HighAvailability)就可以解决上述问题,通过提供选择运行在同一集群中的一个热备用的
"主/备"两个冗余NameNode,允许在机器宕机或系统维护的时候, 快速转移到另一个NameNode。
(二)典型的HA集群
一个典型的HA集群,两个单独的机器配置为NameNodes,在任何时候,一个NameNode 处于活动状态,另一个处于待机状态,活动的NameNode负责处理集群中所有客户端的操
作,待机时仅仅作为一个slave,保持足够的状态,如果有必要提供一个快速的故障转移。
为了保持备用节点与活动节点状态的同步,目前的实现需要两个节点同时访问一个共享存储 设备(例如从NASNFS挂载)到一个目录。将有可能在未来的版本中放宽此限制。
当活动节点对命名空间进行任何修改,它将把修改记录写到共享目录下的一个日志文件,备 用节点会监听这个目录,当发现更改时,它会把修改内容同步到自己的命名空间。备用节点
在故障转移时,它将保证已经读取了所有共享目录内的更改记录,保证在发生故障前的状态 与活动节点保持完全一致。
为了提供快速的故障转移,必须保证备用节点有最新的集群中块的位置信息,为了达到这一 点,Datanode节点需要配置两个nameNode的位置,同时发送块的位置信息和心跳信息到
两个nameNode。
任何时候只有一个namenode处于活动状态,对于HA集群的操作是至关重要的,否则两个节 点之间的状态就会产生冲突,数据丢失或其它不正确的结果,为了达到这个目的或者所谓
的“裂脑场景”出现,管理员必须为共享存储配置至少一个(fencing)方法。在宕机期间, 如果不能确定之间的活动节点已经放弃活动状态,fencing进程负责中断以前的活动节点编辑
存储的共享访问。这可以防止任何进一步的修改命名空间,允许新的活动节点安全地进行故 障转移。
(三)HA架构
HA架构解释如下:
1、只有一个NameNode是Active的,并且只有这个ActiveNameNode能提供服务,改变
NameNode。以后可以考虑让StandbyNameNode提供读服务。
2、提供手动Failover,在升级过程中,Failover在NameNode-DataNode之间写不变的情
况下才能生效。
3、在之前的NameNode重新恢复之后,不能提供failback。
4、数据一致性比Failover更重要。
5、尽量少用特殊的硬件。
6、HA的设置和Failover都应该保证在两者操作错误或者配置错误的时候,不得导致数据损 坏。
7、NameNode的短期垃圾回收不应该触发Failover。
8、DataNode会同时向NameNodeActive和NameNodeStandby汇报块的信息。
NameNodeActive和NameNodeStandby通过NFS备份MetaData信息到一个磁盘上面。
(四)为什么会有HA机制
1、单点故障
在Hadoop 2.0之前,也有若干技术试图解决单点故障的问题,我们在这里做个简短的
总结
A、Secondary NameNode。它不是HA,它只是阶段性的合并edits和fsimage,以缩短集群启动的时间。当NameNode(以下简称NN)失效的时候,Secondary
NN并无法立刻提供服务,Secondary NN甚至无法保证数据完整性:如果NN数据丢失的话,在上一次合并后的文件系统的改动会丢失。
B、Backup NameNode (HADOOP-4539)。它在内存中复制了NN的当前状态,算是Warm
Standby,可也就仅限于此,并没有failover等。它同样是阶段性的做checkpoint,也无法保
证数据完整性。
C、手动把name.dir指向NFS。这是安全的Cold Standby,可以保证元数据不丢失,但集群的恢复则完全靠手动。
D、Facebook AvatarNode。Facebook有强大的运维做后盾,所以Avatarnode只是Hot
Standby,并没有自动切换,当主NN失效的时候,需要管理员确认,然后手动把对外提供服 务的虚拟IP映射到StandbyNN,这样做的好处是确保不会发生脑裂的场景。其某些设计思想和Hadoop2.0里的HA非常相似,从时间上来看,Hadoop2.0应该是借鉴了Facebook的做法。
E、还有若干解决方案,基本都是依赖外部的HA机制,譬如DRBD,Linux HA,VMware的
FT等等。
2、集群容量和集群性能
单NN的架构使得HDFS在集群扩展性和性能上都有潜在的问题,当集群大到一定程度 后,NN进程使用的内存可能会达到上百G,常用的估算公式为1G对应1百万个块,按缺省块
大小计算的话,大概是64T(这个估算比例是有比较大的富裕的,其实,即使是每个文件只有一个块,所有元数据信息也不会有1KB/block)。同时,所有的元数据信息的读取和操作都需
要与NN进行通信,譬如客户端的addBlock、getBlockLocations,还有DataNode的
blockRecieved、sendHeartbeat、blockReport,在集群规模变大后,NN成为了性能的瓶
颈。Hadoop2.0里的HDFSFederation就是为了解决这两个问题而开发的。
(十一)HDFS的新特性Federation
(一)单个Namenode的HDFS架构的局限性
1.Namespace(命名空间)的限制
由于Namenode在内存中存储所有的元数据(metadata),因此单个Namenode所能存储
的对象(文件+块)数目受到Namenode所在JVM的heapsize的限制。50G的heap能够存储20亿(200million)个对象,这20亿个对象支持4000个datanode,12PB的存储(假设文件平均大小为40MB)。
随着数据的飞速增长,存储的需求也随之增长。单个datanode从
4T增长到36T,集群的尺寸增长到8000个datanode。存储的需求从12PB增长到大于
100PB。
2.性能的瓶颈
由于是单个Namenode的HDFS架构,因此整个HDFS文件系统的吞吐量受限于单个
Namenode的吞吐量。毫无疑问,这将成为下一代MapReduce的瓶颈。
3.隔离问题
由于HDFS仅有一个Namenode,无法隔离各个程序,因此HDFS上的一个实验程序就很有可 能影响整个HDFS上运行的程序。那么在HDFSFederation中,可以用不同的Namespace来
隔离不同的用户应用程序,使得不同NamespaceVolume中的程序相互不影响。
4.集群的可用性
在只有一个Namenode的HDFS中,此Namenode的宕机无疑会导致整个集群不可用。
5.Namespace和BlockManagement的紧密耦合
当前在Namenode中的Namespace和Block Management组合的紧密耦合关系会导致如果想要实现另外一套Namenode方案比较困难,而且也限制了其他想要直接使用块存储的应用。
6.为什么纵向扩展目前的Namenode不可行?比如将Namenode的Heap空间扩大到
512GB。
这样纵向扩展带来的第一个问题就是启动问题,启动花费的时间太长。当前具有50GB Heap
Namenode的HDFS启动一次大概需要30分钟到2小时,那512GB的需要多久? 第二个潜在的问题就是Namenode在FullGC时,如果发生错误将会导致整个集群宕机。
第三个问题是对大JVM Heap进行调试比较困难。优化Namenode的内存使用性价比比较低。
(二) 为什么要引入Federation
引入Federation的最主要原因是简单,其简单性是与真正的分布式Namenode相比而言的。
Federation能够快速的解决了大部分单Namenode HDFS的问题。
Federation是简单鲁棒的设计,由于联盟中各个Namenode之间是相互独立的。Federation
整个核心设计实现大概用了3.5个月。大部分改变是在Datanode、Config和Tools,而
Namenode本身的改动非常少,这样Namenode原先的鲁棒性不会受到影响。比分布式的
Namenode简单,虽然这种实现的扩展性比起真正的分布式的Namenode要小些,但是可以 迅速满足需求。另外一个原因是Federation良好的向后兼容性,已有的单Namenode的部署
配置不需要任何改变就可以继续工作。
因此Federation(联盟)是未来可选的方案之一。在Federation架构中可以无缝的支持目前
单Namenode架构中的配置。
(三)HDFS的Federation机制
HDFS Federation使用了多个独立的Namenode/namespace来使得HDFS的命名服务能够水平扩展。在HDFS
Federation中的Namenode之间是联盟关系,他们之间相互独立且不需要相互协调。HDFS
Federation中的Namenode提供了提供了命名空间和块管理功能。HDFS Federation中的datanode被所有的Namenode用作公共存储块的地方。每一个
datanode都会向所在集群中所有的Namenode注册,并且会周期性的发送心跳和块信息报 告,同时处理来自Namenode的指令。
(四)Federation HDFS与当前HDFS的比较及改进
当前HDFS只有一个命名空间(Namespace),它使用全部的块。而FederationHDFS中有多个独立的命名空间(Namespace),并且每一个命名空间使用一个块池(blockpool)。
当前HDFS中只有一组块。而Federation HDFS中有多组独立的块。块池(block pool)就是属于同一个命名空间的一组块。
当前HDFS由一个Namenode和一组datanode组成。而Federation HDFS由多个
Namenode和一组datanode,每一个datanode会为多个块池(block pool)存储块。1.Block
Pool(块池)
所谓Blockpool(块池)就是属于单个命名空间的一组block(块)。每一个datanode为所有的blockpool存储块。Datanode是一个物理概念,而blockpool是一个重新将block划分的逻辑概念。同一个datanode中可以存着属于多个blockpool的多个块。Blockpool允许一个命名空间在不通知其他命名空间的情况下为一个新的block创建BlockID。同时,一个
Namenode失效不会影响其下的datanode为其他Namenode的服务。 当datanode与
Namenode建立联系并开始会话后自动建立Blockpool。每个block都有一个唯一的标识,
这个标识我们称之为扩展的块ID(ExtendedBlockID)=BlockID+BlockID。这个扩展的块
ID在HDFS集群之间都是唯一的,这为以后集群归并创造了条件。
Datanode中的数据结构都通过块池ID(BlockPoolID)索引,即datanode中的
BlockMap,storage等都通过BPID索引。 在HDFS中,所有的更新、回滚都是以
Namenode和BlockPool为单元发生的。即同一HDFS Federation中不同的
Namenode/BlockPool之间没有什么关系。 Hadoop V0.23版本中Block Pool的管理功能依然放在了Namenode中,将来的版本中会将Block
Pool的管理功能移动的新的功能节点中。
2.Datanode的改进
在datanode中,对应于每个Namnode都有一条相应的线程。每个datanode会去每一个
Namenode注册,并且周期性的给所有的Namenode发送心跳及datanode的使用报告。
Datanode还会给Namenode发送其所在的blockpool的blockreport(块报告)。由于有多个Namenode同时存在,因此任何一个Namenode都可以随时动态加入、删除和更新。
3.Federation中的其他方面的改进
提供了工具,对于Namenode的初始化和退役的监控和管理。 允许在datanode级别或者block
pool级别的负载均衡。 Datanode的后台守护进程,为Federation所做的磁盘和目录扫描。
提供了显示Namenode的Block pool的使用状态的Web UI。 还提供了对全部集群存储使用状态的UI展示。
在Web UI中列出了所有的Namenode及其细节,如Namenode-
BlockPoolID和存储的使用状态,失去联系的、活的和死的块信息。还有前往各个Namenode
Web UI的链接。 Datanode退役状态的展示。
4.多命名空间的管理问题
在一个集群中需要唯一的命名空间还是多个命名空间,核心问题命名空间中数据的共享和访 问的问题。使用全局唯一的命名空间是解决数据共享和访问的一种方法。在多命名空间下,
我们还可以使用ClientSideMountTable方式做到数据共享和访问。
5.NamespaceVolume(命名空间卷)
一个Namespace和它的Block Pool合在一起称作Namespace Volume。Namespace
Volume是一个独立完整的管理单元。当一个Namenode/Namespace被删除,与之相对应
的BlockPool也也被删除。在升级时每一个NamespaceVolume也会整体作为一个单元。
6.ClusterID
在HDFSFederation中添加了ClusterID用来区分集群中的每个节点。当格式化一个
Namenode时,这个ClusterID会自动生成或者手动提供。在格式化同一集群中其他
Namenode时会用到这个ClusterID。
7.HDFSFederation对老版本的HDFS是兼容的
这种兼容性可以使得已有的Namenode配置不需要任何改变继续工作。
|