面试HDFS技术原理
HDFS概述:
HDFS(Hadoop Distributed File System)基于Google发布的GFS论文设计开发,运行在通用硬件平台上的分布式文件系统。
其除具有其他分布式文件系统的相同特性外,还有自己特有的特性:
-
高容错性:认为硬件总是不可靠的。 -
高吞吐量:为大量数据访问的应用提供高可用吞吐量支持。 -
大文件存储:支持存储TB-PB级别的数据。
HDFS适合做:大文件存储、流式数据访问。
HDFS不适合做:大量小文件、随机写入、低延迟读取。
HDFS应用场景举例:
HDFS是Hadoop技术框架中的分布式文件系统,对部署在多台独立物理机器上的文件进行管理。
可应用与以下几种场景:
-
网站用户行为数据存储。 -
生态系统数据存储。 -
气象数据存储。
系统设计目标:
(1)硬件失效:
-
硬件的异常比软件的异常更加常见。 -
对于有上百台服务器的数据中心来说,认为总有服务器异常,硬件异常是常态。 -
HDFS需要监测这些异常,并自动恢复数据。
(2)流式数据访问:
-
基于HDFS的应用仅采用流式方式读数据。 -
运行在HDFS上的应用并非以通用业务为目的的应用程序。 -
应用程序关注的是吞吐量,而非响应时间。 -
非POSIX标准接口的数据访问。
(3)存储数据大:
-
运行在HDFS的应用程序有较大的数据需要处理。 -
典型的文件大小为GP到TB级别。
(4)数据一致性:
-
应用程序采用WORM(Write Once Read Many)的数据读写模型。 -
文件仅支持追加,而不允许修改。
(5)多硬件平台:
-
HDFS可运行在不同的硬件平台上。
(6)移动计算能力:
-
计算和存储能力采用就近原则,计算离数据最近。 -
就近原则将有效减少网络的负载,降低网络拥塞。
基本系统架构:
HDFS架构包含三个部分:(NameNode,DateNode,Client)
-
NameDode:用于存储、生成文件系统的元数据、运行一个实例。 -
DateNode:用于存储实际的数据,将自己管理的数据块上报给NameNode,运行多个实例。 -
Client:支持业务访问HDFS,从NameNode,DateNode获取数据返回给业务。多个实例,和业务一起运行。
HDFS数据写入流程:
HDFS数据写入流程如下:
-
业务应用调用HDFS Client提供的API创建文件,请求写入。 -
HDFS Client联系NameNode,NameNode在元数据中创建文件节点。 -
业务应用调用write API写入文件。 -
HDFS Client收到业务数据后,从NameNode获取到数据块编号、位置信息后,联系DateNode,并将要写入数据的DateNode建立起流水线。完成后,客户端再通过自有协议写入数据到DateNode1,再由DateNode1复制到NateNode2,DateNode3. -
写完的数据,将返回确认信息给HDFS Client。 -
所有数据确认完成后,业务调用HDFS CLient关闭文件。 -
业务调用close,flush后HDFS Client联系NameNode,确认数据写完成,NameNode持久化元数据。
HDFS数据读取流程:
HDFS数据读取流程如下:
-
业务调用HDFS Client提供的API打开文件。 -
HDFS Client 联系 NmaeNode,获取到文件信息(数据块、DateNode位置信息)。 -
业务应用调用read API读取文件。 -
HDFS Client根据从NmaeNode获取到的信息,联系DateNode,获取相应的数据块。(Client采用就近原则读取数据)。 -
HDFS Client会与多个DateNode通讯获取数据块。 -
数据读取完成后,业务调用close关闭连接。
HDFS架构关键设计:
元数据持久化:
元数据持久化
元数据持久化流程如下:
-
备NmaeNode通知主NameNode生成新的日志文件,以后的日志写到Editlog.new中,并获取旧的Editlog。 -
备NameNode从注NameNode上获取FSImage文件及位于JournalNode上面的旧Editlog。 -
备NmaeNode将日志和旧的元数据合并,生成新的元数据FSImage.ckpt。 -
备NameNode将元数据上传到主NameNode。 -
主NameNode将上传的原书记进行回滚。 -
循环步骤1.
元数据持久化健壮机制:
HDFS主要目的是保证存储数据完整性,对于各组件的失效,做了可靠性处理。
-
重建失效数据盘的副本数据
DateNode向NmaeNode周期上报失败时,NmaeNode发起副本重建动作以恢复丢失副本。
-
集群数据均衡
HDFS架构设计了数据均衡机制,此机制保证数据在各个DateNode上分布式平均的。
-
数据有效性保证
DateNode数据在读取时校验失败,则从其他数据节点读取数据。
-
元数据可靠性保证
采用日志机制操作元数据,同时元数据存放在主备NameNode上。
快照机制实现了文件系统常见的快照机制,保证数据误操作时,能及时恢复。
-
安全模式
HDFS提供独有的安全模式机制,在数据节点故障时,能防止故障扩散。
HDFS高可靠性(HA):
HDFS高可靠性
HA解决的是一个热备份的问题。
HDFS的高可靠性(HA)架构在基本架构上增加了一下组件:
-
ZooKeeper:分布式协调,主要用来存储HA下的状态文件,主备信息、ZK个数建议3个及以上且为奇数个。 -
NmaeNode主备:NmaeNode主备模式,主提供服务,备合并元数据并作为主的热备。 -
ZKFC(Zookeeper Failover Controller)用于控制NmaeNode节点的主备状态。 -
JN(JournalNode)日志节点:用于共享存储NmaeNode生成的Editlog。
HA
处于待命状态的名称节点和处于活状态的名称节点,它们元数据的两个方面的信息是怎么同步的:
处于待命状态的名称节点当中,它的两方面元数据,一个就是Editlog,它是通过共享存储系统来获得同步的,处于活跃状态的名称节点已发生变化,马上写入到共享存储系统,然后这共享存储系统会通知待命的名称节点把它取走,这样可以保证Editlog上两者可以保持同步。对于映射表信息而言,也就是一个文件包含几个块,这些块被保存到哪个数据节点上面。这种映射信息,它的 实时的维护是通过底层数据节点,不断同时向活跃名称节点和待命节点名称节点汇报来进行维护的。这就是它的基本原理。
HDFS联邦(Federation):
HDFS Federation主要能够解决,单名称节点中存在的以下问题:
-
HDFS集群的扩展性问题。
有了多个名称节点,每个名称节点都可以各自的去管理一部分目录。管理自己对应的子命名空间的子目录,这样就可以让一个集群扩展到更多节点。
在HDFS1.0中会受到内存的限制,制约文件存储数目等限制。一个名称节点存储的文件数目是有限的。
-
性能更高效
多个名称节点各自都管理它不同的数据,而且可以同时对外服务,所以可以提供更高的数据的吞吐率。
-
良好的隔离性
因为它已经根据不同业务数据要求,进行了子空间的划分,某种业务数据可能归某个名称节点管理,另外一种业务数据属于另外一个命名空间,归另外一个名称节点管理。所以不同数据都分给不同名称节点去管理,这样就可以有效地对不同应用程序进行隔离。不会导致一个应用程序消耗过多资源,而影响另外一个应用程序运行的问题。
HDFS不能解决单点故障问题。
数据副本机制:
副本距离计算公式:
-
Distance(Rack1/D1,Rack1/D1)= 0 ,同一台服务器的距离为0. -
Distance (Rack1/D1, Rack1/D3) = 2;同一机架不同的服务器距离为2. -
DIstance(Rack1/D1, Rack2/D1)= 4 ;不同机架的服务器距离为4.
副本放置策略:
-
第一个副本在本地机器。 -
第二个副本在远端机架的节点。 -
第三个副本看之前连个副本是否在同一机架,如果是则选择其他机架,否则选择和第一个副本相同机架的不同节点。 -
第四个及以上,随机选择副本存放位置。
配置HDFS数据存储策略:
默认情况下,HDFS NmaeNode自动选择DateNode保存数据的副本。在实际义务中,存在以下场景:
-
DateNode上存在的不同存储设备,数据需要选择一个合适的设备分级存储数据。 -
DateNode不同目录中的数据重要程度不同,数据需要根据目录标签选择一个格式的DateNode节点保存。 -
DateNode集群使用了异构服务器,关键数据需要保存在具有高度可靠性的节点组中。
配置DateNode使用分级存储:
-
HDFS的分级存储框架提供了RAM_DISK(内存盘)、DISK(机械硬盘)、ARCHIVE(高密度低成本存储介质)、SSD(固态硬盘)四种存储类型的存储设备。 -
通过对四种存储类型进行合理组合,即可形成使用与不公场景的存储策略。
配置标签存储策略:
配置DateNode使用标签存储:
用户通过数据特征灵活配置HDFS数据块存放策略,即为一个HDFS目录设置一个标签表达式,每个DateNode可以对应一个或多个标签;当基于标签的数据块存放策略为指定目录下的文件选择DateNode节点进行存放时,根据文件的标签表达式选择出将要存放的DateNode节点范围,然后在这个DateNode节点范围内,遵守下一个指定的数据块存放策略进行存放。
配置DateNode使用节点组存储:
配置DateNode使用节点组存储:
关键数据根据实际业务需要保存在具有高度可靠性的节点中,此时DateNode组成了异构集群。通过修改DateNode的存储策略,系统可以将数据强制保存在指定的节点组中。
使用约束:
-
第一份副本将从强制机架组(机架组2)中选出,如果在强制机架组中没用可用节点,则写入失败。 -
第二份副本将从本地客户端机器或机架组中的随机节点(当客户端机架组不为强制机架组时)选出。 -
第三份副本将从其他机架组中选出。 -
各副本应放在不同的机架组中。如果所需副本的数量大于可用的机架组数量,则会将多出的副本存放在随机机架组中。
Colocation同分布:
同分布(Colocation)的定义:将存在关联关系的数据或可能要进行关联操作的数据存储在相同的存储节点上。
按照下图存放,假设要将文件A和文件D进行关联操作,此时不可避免地要进行大量的数据搬迁,整个集群将由于数据传输占用大量网络带宽,严重影响大数据的处理速度与系统性能。
HDFS文件同分布的特性,将那些需要进行关联操作的文件存放在相同的数据节点上,在进行关联操作计算是避免了到其他数据节点上获取数据,大大降低了网络带宽的占用。
使用同分布特性,文件A、D进行join时,由于其对应的block都在相同的节点,因此大大降低了资源消耗。如下图:
效果图
HDFS架构其他关键设计要点说明:
-
统一的文件系统:
HDFS对外仅呈现一个统一的文件系统。
-
统一的通讯协议:
统一采用RPC方式通信、NmaeNode被动的接收Client,DateNode的RPC请求。
-
空间回收机制:
支持回收站机制,以及副本数的动态设置机制。
-
数据组织:
数据存储以数据块为单位,存储在操作系统的HDFS文件系统上。
-
访问方式:
提供Java API,http,shell方式访问HDFS数据。
常用的shell命令:
NameNode和DateNode的对比:
NameNode | DateNode |
---|---|
存储文件内容 | |
文件内容保存在磁盘 | |
保存文件,block,DateNode之间的映射关系 | 维护了block id到datenode本地文件的映射关系。 |
名称节点的数据结构:
-
在HDFS中,名称节点(NameNode)负责管理分布式文件系统的命名空间(Namespace),保存了两个核心的数据结构,即FsImage和EditLog
-
-
FsImage用于维护文件系统树以及文件树中所有的文件和文件夹的元数据 -
操作日志文件EditLog中记录了所有针对文件的创建、删除、重命名等操作 -
名称节点记录了每个文件中各个块所在的数据节点的位置信息
FsImage文件:
FsImage文件包含文件系统中所有目录和文件inode的序列化形式。每个inode是一个文件或目录的元数据的内部表示,并包含此类信息:文件的复制等级、修改和访问时间、访问权限、块大小以及组成文件的块。对于目录,则存储修改时间、权限和配额元数据.
FsImage文件没有记录块存储在哪个数据节点。而是由名称节点把这些映射保留在内存中,当数据节点加入HDFS集群时,数据节点会把自己所包含的块列表告知给名称节点,此后会定期执行这种告知操作,以确保名称节点的块映射是最新的。
名称节点的启动:
-
在名称节点启动的时候,它会将FsImage文件中的内容加载到内存中,之后再执行EditLog文件中的各项操作,使得内存中的元数据和实际的同步,存在内存中的元数据支持客户端的读操作。 -
一旦在内存中成功建立文件系统元数据的映射,则创建一个新的FsImage文件和一个空的EditLog文件。 -
名称节点起来之后,HDFS中的更新操作会重新写到EditLog文件中,因为FsImage文件一般都很大(GB级别的很常见),如果所有的更新操作都往FsImage文件中添加,这样会导致系统运行的十分缓慢,但是,如果往EditLog文件里面写就不会这样,因为EditLog 要小很多。每次执行写操作之后,且在向客户端发送成功代码之前,edits文件都需要同步更新。
名称节点运行期间Editlog不断变大的问题:
-
在名称节点运行期间,HDFS的所有更新操作都是直接写到EditLog中,久而久之, EditLog文件将会变得很大。 -
虽然这对名称节点运行时候是没有什么明显影响的,但是,当名称节点重启的时候,名称节点需要先将FsImage里面的所有内容映像到内存中,然后再一条一条地执行EditLog中的记录,当EditLog文件非常大的时候,会导致名称节点启动操作非常慢,而在这段时间内HDFS系统处于安全模式,一直无法对外提供写操作,影响了用户的使用。
如何解决?答案是:SecondaryNameNode第二名称节点
第二名称节点是HDFS架构中的一个组成部分,它是用来保存名称节点中对HDFS 元数据信息的备份,并减少名称节点重启的时间。SecondaryNameNode一般是单独运行在一台机器上。
SecondaryNameNode的工作情况:
(1)SecondaryNameNode会定期和NameNode通信,请求其停止使用EditLog文件,暂时将新的写操作写到一个新的文件edit.new上来,这个操作是瞬间完成,上层写日志的函数完全感觉不到差别;
(2)SecondaryNameNode通过HTTP GET方式从NameNode上获取到FsImage和EditLog文件,并下载到本地的相应目录下;
(3)SecondaryNameNode将下载下来的FsImage载入到内存,然后一条一条地执行EditLog文件中的各项更新操作,使得内存中的FsImage保持最新;这个过程就是EditLog和FsImage文件合并;
(4)SecondaryNameNode执行完(3)操作之后,会通过post方式将新的FsImage文件发送到NameNode节点上 (5)NameNode将从SecondaryNameNode接收到的新的FsImage替换旧的FsImage文件,同时将edit.new替换EditLog文件,通过这个过程EditLog就变小了。
数据节点:
-
数据节点是分布式文件系统HDFS的工作节点,负责数据的存储和读取,会根据客户端或者是名称节点的调度来进行数据的存储和检索,并且向名称节点定期发送自己所存储的块的列表。 -
每个数据节点中的数据会被保存在各自节点的本地Linux文件系统中。
推荐阅读:
end