HDFS基本原理

HDFS针对的使用场景是数据读写具有“一次写,多次读”的特征。HDFS保证一个文件在一个时刻只被一个调用者执行写操作,而可以被多个调用者执行读操作。

HDFS结构

HDFS结构

HDFS是一个Master/Slave的架构,在Master上运行NameNode,而在每一个Slave上运行DataNode,ZKFC需要和NameNode一起运行。

  • 各模块的功能说明如下所示:
  • NameNode

    用于管理文件系统的命名空间、目录结构、元数据信息以及提供备份机制等,分为

    Active NameNode、Standby NameNode、Observer NameNode。

    DataNode

    用于存储每个文件的“数据块”数据,并且会周期性地向NameNode报告该DataNode的数据存放情况。

    JournalNode

    HA集群下,用于同步主备NameNode之间的元数据信息。

    ZKFC

    ZKFC是需要和NameNode一一对应的服务,即每个NameNode都需要部署ZKFC。它负责监控NameNode的状态,并及时把状态写入ZooKeeper。ZKFC也有选择谁作为Active NameNode的权利。

    ZK Cluster

    ZooKeeper是一个协调服务,帮助ZKFC执行主NameNode的选举。

    HttpFS gateway

    HttpFS是个单独无状态的gateway进程,对外提供webHDFS接口,对HDFS使用FileSystem接口对接。可用于不同Hadoop版本间的数据传输,及用于访问在防火墙后的HDFS(HttpFS用作gateway)。

HDFS HA架构

HDFS HA架构

HA即为High Availability,用于解决NameNode单点故障问题,该特性通过主备的方式为主NameNode提供一个备用者,一旦主NameNode出现故障,可以迅速切换至备NameNode,从而不间断对外提供服务。

  • HA架构介绍
  • 在一个典型HDFS HA场景中,通常由两个NameNode组成,一个处于Active状态,另一个处于Standby状态。

    为了能实现Active和Standby两个NameNode的元数据信息同步,需提供一个共享存储系统。本版本提供基于QJM(Quorum Journal Manager)的HA解决方案,如图2所示。主备NameNode之间通过一组JournalNode同步元数据信息。

    通常配置奇数个(2N+1个)JournalNode,且最少要运行3个JournalNode。这样,一条元数据更新消息只要有N+1个JournalNode写入成功就认为数据写入成功,此时最多容忍N个JournalNode写入失败。比如,3个JournalNode时,最多允许1个JournalNode写入失败,5个JournalNode时,最多允许2个JournalNode写入失败。

    由于JournalNode是一个轻量级的守护进程,可以与Hadoop其它服务共用机器。建议将JournalNode部署在控制节点上,以避免数据节点在进行大数据量传输时引起JournalNode写入失败。

HDFS原理

HDFS原理

MRS使用HDFS的副本机制来保证数据的可靠性,HDFS中每保存一个文件则自动生成1个备份文件,即共2个副本。HDFS副本数可通过“dfs.replication”参数查询。

  • Core节点与HDFS默认副本的关系:
  • 当MRS集群中Core节点规格选择为非本地盘(hdd)时,若集群中只有一个Core节点,则HDFS默认副本数为1。若集群中Core节点数大于等于2,则HDFS默认副本数为2。


    当MRS集群中Core节点规格选择为本地盘(hdd)时,若集群中只有一个Core节点,则HDFS默认副本数为1。若集群中有两个Core节点,则HDFS默认副本数为2。若集群中Core节点数大于等于3,则HDFS默认副本数为3。

  • MRS服务的HDFS组件支持以下部分特性:
  • HDFS组件支持纠删码,使得数据冗余减少到50%,且可靠性更高,并引入条带化的块存储结构,最大化的利用现有集群单节点多磁盘的能力,使得数据写入性能在引入编码过程后,仍和原来多副本冗余的性能接近。


    支持HDFS组件上节点均衡调度和单节点内的磁盘均衡调度,有助于扩容节点或扩容磁盘后的HDFS存储性能提升。

HDFS与其他组件的关系

  • HDFS和HBase的关系

    HDFS是Apache的Hadoop项目的子项目,HBase利用Hadoop HDFS作为其文件存储系统。HBase位于结构化存储层,Hadoop HDFS为HBase提供了高可靠性的底层存储支持。除了HBase产生的一些日志文件,HBase中的所有数据文件都可以存储在Hadoop HDFS文件系统上。

    HDFS是Apache的Hadoop项目的子项目,HBase利用Hadoop HDFS作为其文件存储系统。HBase位于结构化存储层,Hadoop HDFS为HBase提供了高可靠性的底层存储支持。除了HBase产生的一些日志文件,HBase中的所有数据文件都可以存储在Hadoop HDFS文件系统上。

  • HDFS和MapReduce的关系

    HDFS是Hadoop分布式文件系统,具有高容错和高吞吐量的特性,可以部署在价格低廉的硬件上,存储应用程序的数据,适合有超大数据集的应用程序。

    而MapReduce是一种编程模型,用于大数据集(大于1TB)的并行运算。在MapReduce程序中计算的数据可以来自多个数据源,如Local FileSystem、HDFS、数据库等。最常用的是HDFS,可以利用HDFS的高吞吐性能读取大规模的数据进行计算。同时在计算完成后,也可以将数据存储到HDFS。

    HDFS是Hadoop分布式文件系统,具有高容错和高吞吐量的特性,可以部署在价格低廉的硬件上,存储应用程序的数据,适合有超大数据集的应用程序。

    而MapReduce是一种编程模型,用于大数据集(大于1TB)的并行运算。在MapReduce程序中计算的数据可以来自多个数据源,如Local FileSystem、HDFS、数据库等。最常用的是HDFS,可以利用HDFS的高吞吐性能读取大规模的数据进行计算。同时在计算完成后,也可以将数据存储到HDFS。

  • HDFS和Spark的关系

    通常,Spark中计算的数据可以来自多个数据源,如Local File、HDFS等。最常用的是HDFS,用户可以一次读取大规模的数据进行并行计算。在计算完成后,也可以将数据存储到HDFS。

    分解来看,Spark分成控制端(Driver)和执行端(Executor)。控制端负责任务调度,执行端负责任务执行。

    通常,Spark中计算的数据可以来自多个数据源,如Local File、HDFS等。最常用的是HDFS,用户可以一次读取大规模的数据进行并行计算。在计算完成后,也可以将数据存储到HDFS。

    分解来看,Spark分成控制端(Driver)和执行端(Executor)。控制端负责任务调度,执行端负责任务执行。

  • HDFS和ZooKeeper的关系

    ZKFC(ZKFailoverController)作为一个ZooKeeper集群的客户端,用来监控NameNode的状态信息。ZKFC进程仅在部署了NameNode的节点中存在。HDFS NameNode的Active和Standby节点均部署有zkfc进程。

    1.HDFS NameNode的ZKFC连接到ZooKeeper,把主机名等信息保存到ZooKeeper中,即“/hadoop-ha”下的znode目录里。先创建znode目录的NameNode节点为主节点,另一个为备节点。HDFS NameNode Standby通过ZooKeeper定时读取NameNode信息。

    2.当主节点进程异常结束时,HDFS NameNode Standby通过ZooKeeper感知“/hadoop-ha”目录下发生了变化,NameNode会进行主备切换。

    ZKFC(ZKFailoverController)作为一个ZooKeeper集群的客户端,用来监控NameNode的状态信息。ZKFC进程仅在部署了NameNode的节点中存在。HDFS NameNode的Active和Standby节点均部署有zkfc进程。

    1.HDFS NameNode的ZKFC连接到ZooKeeper,把主机名等信息保存到ZooKeeper中,即“/hadoop-ha”下的znode目录里。先创建znode目录的NameNode节点为主节点,另一个为备节点。HDFS NameNode Standby通过ZooKeeper定时读取NameNode信息。

    2.当主节点进程异常结束时,HDFS NameNode Standby通过ZooKeeper感知“/hadoop-ha”目录下发生了变化,NameNode会进行主备切换。


华为云MRS基于开源HDFS做了哪些特性增强?

华为云MRS基于开源HDFS做了哪些特性增强?

  • 文件块同分布(Colocation)

    离线数据汇总统计场景中,Join是一个经常用到的计算功能,在MapReduce中的实现方式大体如下:

    1. Map任务分别将两表文件的记录处理成(Join Key,Value),然后按照Join Key做Hash分区后,送到不同的Reduce任务里去处理。
    2. Reduce任务一般使用Nested Loop方式递归左表的数据,并遍历右表的每一行,对于相等的Join Key,处理Join结果并输出。
    3. 以上方式的最大问题在于,由于数据分散在各节点上,所以在Map到Reduce过程中,需要大量的网络数据传输,使得Join计算的性能大大降低,该过程如图1所示:

    图1 无同分布数据传输流程

    由于数据表文件是以HDFS Block方式存放在物理文件系统中,如果能把两个需要Join的文件数据块按Join Key分区后,一一对应地放在同一台机器上,则在Join计算的Reduce过程中无需传递数据,直接在节点本地做Map Join后就能得到结果,性能显著提升。

    HDFS数据同分布特性,使得需要做关联和汇总计算的两个文件FileA和FileB,通过指定同一个分布ID,使其所有的Block分布在一起,不再需要跨节点读取数据就能完成计算,极大提高MapReduce Join性能。

  • 硬盘坏卷设置

    在开源版本中,如果为DataNode配置多个数据存放卷,默认情况下其中一个卷损坏,则DataNode将不再提供服务。配置项“dfs.datanode.failed.volumes.tolerated”可以指定失败的个数,小于该个数,DataNode可以继续提供服务。

    “dfs.datanode.failed.volumes.tolerated”取值范围为-1~DataNode上配置的磁盘卷数,默认值为-1,效果如图2所示。

    图2 选项设置为0

  • HDFS启动加速

    在HDFS中,NameNode启动需要加载元数据文件fsimage,然后等待DataNode完成启动并上报数据块信息。当DataNode上报的数据块信息达到设定百分比时,NameNode退出Safemode,完成启动过程。当HDFS上保存的文件数量达到千万甚至亿级以后,以上两个过程都要耗费大量的时间,致使NameNode的启动过程变得非常漫长。该版本对加载元数据fsimage这一过程进行了优化。


    在开源HDFS中,fsimage里保存了所有类型的元数据信息,每一类元数据信息(如文件元数据信息和文件夹元数据信息)分别保存在一个section块里,这些section块在启动时是串行加载的。当HDFS上存储了大量的文件和文件夹时,这两个section的加载就会非常耗时,影响HDFS文件系统的启动时间。HDFS NameNode在生成fsimage时可以将同一类型的元数据信息分段保存在多个section里,当NameNode启动时并行加载fsimage中的section以加快加载速度。

  • 基于标签的数据块摆放策略(HDFS Nodelabel)

    用户需要通过数据特征灵活配置HDFS文件数据块的存储节点。通过设置HDFS目录/文件对应一个标签表达式,同时设置每个DataNode对应一个或多个标签,从而给文件的数据块存储指定了特定范围的DataNode。当使用基于标签的数据块摆放策略,为指定的文件选择DataNode节点进行存放时,会根据文件的标签表达式选择出将要存放的Datanode节点范围,然后在这些Datanode节点范围内,选择出合适的存放节点。

    1. 支持用户将数据块的各个副本存放在指定具有不同标签的节点,如某个文件的数据块的2个副本放置在标签L1对应节点中,该数据块的其他副本放置在标签L2对应的节点中。
    2. 支持选择节点失败情况下的策略,如随机从全部节点中选一个。

    如图3所示。

    1. /HBase下的数据存储在A,B,D
    2. /Spark下的数据存储在A,B,D,E,F
    3. /user下的数据存储在C,D,F
    4. /user/shl下的数据存储在A,E,F

    图3 基于标签的数据块摆放策略样例

  • HDFS Load Balance

    HDFS的现有读写策略主要以数据本地性优先为主,并未考虑节点或磁盘的实际负载情况。HDFS Load Balance功能是基于不同节点的I/O负载情况,在HDFS客户端进行读写操作时,尽可能地选择I/O负载较低的节点进行读写,以此达到I/O负载均衡,以及充分利用集群整体吞吐能力。


    写文件时,如果开启写文件的HDFS Load Balance功能,NameNode仍然是根据正常顺序(本地节点—本机架—远端机架)进行DataNode节点的选取,只是在每次选择节点后,如果该节点I/O负载较高,会舍弃并从其他节点中重新选取。


    读文件时,Client会向NameNode请求所读Block所在的DataNode列表。NameNode会返回根据网络拓扑距离进行排序的DataNode列表。开启读取的HDFS Load Balance功能时,NameNode会在原先网络拓扑距离排序的基础上,根据每个节点的平均I/O负载情况进行顺序调整,把高I/O负载的节点顺序调整至后面。

  • HDFS冷热数据迁移

    Hadoop历来主要被用于批量处理大规模的数据。相比处理低时延,批处理应用更关注原始数据处理的吞吐量,因此,目前已有的HDFS模型都运作良好。

    然而,随着技术的发展,Hadoop逐渐被用于以随机I/O访问模式的操作为主的上层应用上,如Hive、HBase等,而这种时延要求较高的场景中,低时延的高速磁盘(如SSD磁盘)可以得到广泛的应用。为了支持这种特性,HDFS现在支持了异构存储类型,这样用户就可以根据自己不同的业务需求场景来选择不同的数据存储类型。

    因此,HDFS可以根据数据的热度,选择不同的存储策略。如将HDFS上频繁访问多次的数据被标识为ALL_SSD或HOT,被访问几次的可以标识为WARM,而只有访问1~2次甚至更少的可以被标识为COLD等,如下图为不同的数据热度,可以选择不同的数据存储策略。

    但是,这些高速低时延磁盘,例如SSD磁盘,通常比机械磁盘贵很多。大部分用户希望只有那些经常被访问的热数据才能一直被存储在昂贵的高速磁盘上,而随着数据的访问热度下降以及时间的老化,这些数据应该被迁移到价格低廉的存储介质上。


    以详单查询场景作为典型的用例场景,进行说明:当最新详单数据刚刚被导入HDFS上时,会被上层业务人员频繁查询,所以为了提高查询性能,可以将这些详单数据最先导入到SSD磁盘中;但是随着时间的迁移,这些数据逐渐被老化,访问频度越来越低,这时便不适合继续存储在高速硬盘上,需要迁移到廉价的存储介质,节省成本。


    因此,能够基于数据的age自动识别出老化的数据,并将它们迁移到价格低廉的存储介质(如Disk/Archive)上,会给用户节省很高的存储成本,提高数据管理效率。

    HDFS Auto Data Movement工具是HDFS冷热数据迁移的核心,根据数据的使用频率自动识别数据冷热设定不同的存储策略。该工具主要支持以下功能:

    根据数据的age,access time和手动迁移规则,将数据存储策略标识为All_SSD/One_SSD/Hot/Warm/Cold。

    根据数据age,access time和手动迁移规则,定义区分冷热数据的规则。

    定义基于age的规则匹配时要采取的行为操作。

    MARK,表示只会基于age规则标识出数据的冷热度,并标记出对应的存储策略。MOVE表示基于age规则识别出相应的数据冷热度,并标记出对应的存储策略后,并触发HDFS Auto Data Movement工具进行数据搬迁。

    MARK:识别数据是否频繁或很少使用的行为操作,并设置数据存储策略。

    MOVE:调用HDFS冷热数据迁移工具并跨层迁移数据的行为操作。

    SET_REPL:为文件设置新的副本数的行为操作。

    MOVE_TO_FOLDER:将文件移动到目标文件夹的行为操作。

    DELETE:删除文件/目录的行为操作。

    SET_NODE_LABEL:设置文件节点标签(NodeLabel)的操作。

    使用HDFS冷热数据迁移功能,只需要定义age,基于access time的规则。由HDFS冷热数据迁移工具来匹配基于age的规则的数据,设置存储策略和迁移数据。以这种方式,提高了数据管理效率和集群资源效率。

  • HDFS更多信息

    关于HDFS更多详细介绍,请参考HDFS组件介绍

    关于HDFS的使用,请参考使用HDFS