HDFS架构(官方文档翻译)

HDFS是一种分布式文件系统,设计用于处理大规模数据集,具有高容错性和高吞吐量。系统由NameNode和DataNode组成,NameNode管理文件系统命名空间和元数据,DataNode存储数据并处理读写请求。文件被分割为块并复制以确保容错性,副本通常分布在不同机架上以优化性能。NameNode通过心跳和Blockreport监控DataNode状态,确保数据完整性。HDFS支持快照、空间回收和多种访问方式,如FSShell和DFSAdmin。安全模式和元数据持久性策略保证了系统的稳定运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HDFS的架构

HDFS是一种可以运行在廉价的服务器上的文件系统,具有高度容错的特性。它可以提供对大规模数据集的高吞吐量的访问,适用于基于大量数据的应用。HDFS最初是Apache Nutch(web搜索引擎项目)的基础架构,现在已经成为Apache Hadoop核心项目的一部分。

HDFS构想和目标
  • 硬件故障

    一个hdfs文件系统实例可能有成百上千个服务器构成,每个服务器存储文件系统的一部分数据。事实上,硬件故障是常态,构成hdfs的服务器组件发生故障是大概率事件,这也意味着总有部分服务器因为故障而变得不可用。因此,故障的探测以及从这些故障中自动、快速的恢复是hdfs架构设计的一个核心目标。

  • 大规模数据集

    hdfs上的一个文件的大小可能是GB到TB级别,hdfs需要优化大文件的存储。它应该提供高聚合的数据带宽并扩展到单个集群中的数百个节点。一个hdfs实例中应该支持成千上万个文件的存储。

  • 简化一致性模型

    hdfs应用需要一个对文件“一次写入多次读取”的访问模型。一个文件一旦创建、写入、关闭后就不应该再被修改,除了追加append操作和情况truncate操作。hdfs应该支持对文件的追加而不支持对任意位置的修改。这种设想简化了数据的一致性问题并且能极大提高数据访问的吞吐量,并完美适用于MapReduce和网络爬虫应用。

  • “移动计算成本远小于移动数据”

    计算操作如果距离操作的数据近(网络上的距离,最理想的就是在一台机器上)的话效率往往更高,尤其是在大规模数据集的情况下。这种移动计算的设想最小化了网络阻塞,增加了系统的整体吞吐量(不需要传输大量数据到应用所在的节点上)。hdfs提供了接口来将应用程序分配到数据所在的节点上。

  • 跨硬件和软件平台的可移植性

    hdfs被设计为可以容易的从一个平台移植到另一个平台,这种特性有助于hdfs被广泛采用为作为大规模应用的基础平台。

NameNode和DataNodes
  • hdfs采用主从架构,由一个NameNode节点和多个DataNode节点构成,其中NameNode所在的服务器(主)起到管理hdfs的命名空间和限制客户端对文件访问的作用。而DataNode则主要负责其所在服务器的数据的存储,通常情况下,集群中的每个服务器都有一个DataNode进程(一个服务器上有多个DataNode进程也可以,但不常见)。DataNode提供了对文件数据的存储,更底层的说,是以block的形式来存储数据的。一个文件会被拆分为多个block存储在多个DataNode中。NameNode执行对元数据的操作如打开、关闭、重命名文件和目录等,它还决定了block到DataNode的映射。DataNode则负责接收客户端的读写请求,并在NameNode的指导下对block进行创建、删除、复制操作。

在这里插入图片描述

图中的Namenode和Datanode其实就是运行在服务器上的进程,通常用一台专用的服务器运行Namenode进程,其余的服务器每台运行一个Datanode进程。Namenode负责处理元数据,而Datanode则负责用户数据的读写。这些服务器通常需要配备GNU/Linux的操作系统,同时具备java环境。因为hdfs是基于java开发的,这也使得hdfs易于使用。

单个Namemode的结构设计简化了hdfs的架构,Namenode就像一个仲裁者,负责存储hdfs所有的元数据,文件数据不会存入Namenode。

文件系统命名空间
  • hdfs支持传统的层次化文件组织形式,它的结构和现有的一些文件系统相似,用户或应用可以创建目录/文件、移动、重命名文件等等。hdfs支持用户配额(user quotas,用户配额就是对以某个文件为根的目录和文件数量的硬限制;还有space quotas,就是对字节数的限制)和访问权限(如用户对文件的读写权限等)的设置。hdfs不支持硬链接和软链接,当然它的架构也不排除这些特性的实现。

  • NameNode负责维护文件系统的命名空间。对文件系统命名空间或其属性的任何更改都由NameNode记录。一个应用程序可以指定HDFS维护的文件副本数量。一个文件的副本数称为该文件的副本因子( replication factor),该信息由NameNode存储。

数据副本
  • 一个hdfs集群可以实现对一个超大文件的跨机器存储。一个大文件会被分割为一系列的block。这些block会复制副本,目的是为了容错和故障恢复。可以手动配置block的大小和副本数量
  • 属于一个文件的blocks,除了最后一个block,其余block的size都是一样的。而在hdfs添加了对可变长度块的支持后,用户可以开始一个新的块,而不需要将最后一个块填充到配置的块大小。
  • 应用程序可以指定文件的副本数量。副本因子可以在文件创建时指定,以后也可以更改。HDFS中的文件是只写一次的(除了追加和清空),并且在任何时候都只有一个writer。
  • NameNode做出关于block replication的所有决定。它定期从集群中的每个Datanode接收一个Heartbeat和一个Blockreport。接收到Heartbeat表示该DataNode功能正常。Blockreport则包含DataNode上所有block 的列表。
    在这里插入图片描述
副本放置

副本的放置对HDFS的可靠性和性能至关重要。优化的副本放置使HDFS有别于其他分布式文件系统。基于机架感知的副本放置策略可以提高数据可靠性、可用性和网络带宽利用率。当前hdfs的副本放置策略正是向机架感知策略方向迈出的第一步。实现该策略的短期目标是在生产环境上验证它,对其特性有更好的理解,并以此为基础测试和研究更复杂的策略。

大型HDFS实例是运行在一个计算机集群上的,该集群通常分布在许多机架上。不同机架上的两个节点之间的通信必须通过交换机。在大多数情况下,同一机架机器之间的网络带宽大于不同机架机器之间的网络带宽。

NameNode通过Hadoop Rack Awareness中描述的过程确定每个DataNode所属的机架号。一个简单但非最优的策略就是把各个副本放在独立的机架上,比如3个副本,放在3台机架上。这可以防止在整个机架发生故障时丢失数据,同时读取数据时可以使用多个机架的带宽。这种策略可以均衡的放置副本,在发生机器故障时很容易的可以实现集群的负载均衡,但是该策略的写入消耗比较大,因为block需要在不同机器上传输。

大多数情况下,采取这样的副本放置策略:如果副本数是3,如Writer所在节点为DataNode节点,则第一个副本放置于该节点上,反之随机选择一个和Writer所在节点处于同一机架的DataNode节点。其余两个副本放置于相同的机架上不同的节点中。这种策略可以在减少机架间传输数据量的同时降低写入消耗。由于机架的故障率远远小于节点的故障率,因此这样的策略并不影响对数据可靠性和可用性的需求。

如果副本数大于3,那么多出的副本就随机放置,只需满足机架上的最大副本数小于(replicas - 1) / racks + 2即可。由于NameNode不允许一个DataNode上有相同的副本,因此最大副本数就是DataNode的数量。

将对Storage Types and Storage Policies的支持添加到 HDFS 后,除了上述机架感知策略外,NameNode 也将这种副本放置策略纳入考虑。 NameNode 首先基于机架感知选择datanode,然后检查候选节点是否具有与待存储文件设置的存储策略匹配的存储类型。 如果候选节点没有该存储类型,NameNode 会寻找另一个节点。 如果在第一条路径中找不到足够的节点来放置副本,NameNode 会在第二条路径中查找具有fallback storage types类型的节点。

这里描述的默认副本放置策略仍然处于开发研究进程中。

副本选择

为了最小化全局带宽和读取延迟,hdfs的读取请求会尝试返回距离reader最近的副本。如果存在与读取节点处于同一机架的副本,则该副本优先返回。如果hdfs集群跨越了多个数据中心,那么本地数据中心的副本比远程的优先级更高,

Block放置策略

出了副本放置部分描述的策略外,hdfs还提供了4中可插拔的放置策略,详见 Block Placement Policies,用户可以根据自己的实际需求选择合适的策略,默认使用的是BlockPlacementPolicyDefault策略,也就是上面描述的三个副本位于两个机架的策略。

安全模式

在启动时,NameNode进入一个叫做Safemode的特殊状态。NameNode处于Safemode状态时,不会进行数据块的复制。NameNode接收datanode发来的Heartbeat(心跳)和Blockreport消息,Blockreport包含该DataNode所承载的数据块列表,这样NameNode就拿到了block位置及其副本信息。每个块都有指定的最小副本数量,当数据块的最小副本数已经签入NameNode时(被namenode发现),该block被认为是安全复制的。NameNode有一个可配置的安全复制的block数量的百分比,当超过这个百分比并过30s后,Namenode就会退出Safemode模式。之后NameNode会确认到它那登记的副本数量少于指定的最小副本数的block的列表,然后把对应的block复制到其它DataNode。

文件系统元数据的持久性

HDFS 的命名空间namespace由 NameNode 存储。 NameNode 使用 EditLog (事务日志)来持久化的记录元数据发生的每个更改。 例如,在 HDFS 中创建一个新文件会导致 NameNode 在 EditLog 中插入一条记录来代表这个操作。 类似地,更改文件的replication factor也会插入新记录到 EditLog 中。 NameNode 使用其本地主机的文件系统来存储 EditLog。 整个hdfs的命名空间,包括块到文件和文件系统属性的映射,都存储在一个名为 FsImage 的文件中。 FsImage 也存储在 NameNode 的本地文件系统中。

NameNode在内存中保留了一个代表整个文件系统命名空间和Blockmap(块映射)的image。当NameNode启动,或者由一个可配置的阈值触发checkpoint时,NameNode会从磁盘读取FsImage和EditLog,将EditLog中的所有事务应用到内存中,生成新版本的FsImage并刷新到磁盘上。旧的EditLog就可以被删除了因为所有的事物数据都已经持久化到了FsImage上,这个过程就称作一个checkpoint。checkpoint的目的是通过获取文件系统元数据的快照并将其保存到FsImage中,来确保HDFS文件系统元数据的一致性。尽管读取FsImage是有效的,但直接对FsImage进行增量编辑是低效的。因此hdfs不是每次编辑都修改FsImage,而是将编辑持久化到Editlog中。在checkpoint期间,再将来自Editlog的更改应用到FsImage中。检查点可以在给定的时间间隔(dfs.namenode.checkpoint.period)(以秒为单位)触发,也可以在文件系统事务累积后触发(dfs.namenode.checkpoint.txns)。如果同时设置了这两个属性,则第一个达到的阈值将触发一个checkpoint。

DataNode 将 HDFS 数据存储在其本地文件系统中的文件中。 DataNode 对 HDFS 文件一无所知,它只是将每个数据块存储在其本地文件系统中的一个单独文件中。DataNode不会在同一个目录中创建所有文件,因为本地文件系统可能无法有效地支持单个目录中存储大量的文件,相反,它使用启发式算法来确定每个目录的最佳文件数量,并适当地创建子目录。当 DataNode 启动时会扫描其本地文件系统,生成与这些本地文件对应的所有 HDFS 数据块的列表,并将此报告发送到 NameNode。 这个报告就是上文提高的,在safemode时和HeartBeat一起传给NameNode的Blockreport。

通信协议

所有 HDFS 通信协议都位于 TCP/IP 协议之上。 客户端建立一个 到NameNode 机器上TCP 端口(可配置)的连接,客户端通过ClientProtocol 和NameNode交互,DataNode通过DataNode Protocol和NameNode交互。一个RPC请求抽象包装了Client协 和DataNode协议。NameNode不会初始化任何RPC请求,它只是对来自客户端和DataNode的请求作出响应。

鲁棒性

hdfs的核心设计就是在出现故障时也能保证存储数据的可靠性,三种常见的故障为:NameNode故障,DataNode故障和网络分区。

数据磁盘故障,心跳和再复制

每个DataNode都会在一个固定的时间周期向NameNode发送Heartbeat,但是网络分区问题会造成一部分DataNode失去和NameNode的联系。NameNode通过没收到Heartbeat来识别这种问题。NameNode把这些失去心跳的DataNode标记为dead,这些节点将不再接受IO请求。任何存储在该DataNode上的数据对于hdfs都变得不可用了,因此会造成一些block的副本数量小于指定的副本数。NameNod会持续跟踪哪些块需要被复制,并在必要时启动复制。需要NameNode启动重新复制的原因有很多: 如DataNode不可用、副本损坏、DataNode上的硬盘故障、文件副本因子增大等。

集群再均衡

HDFS架构支持数据再平衡方案。如果DataNode上的空闲空间低于某个阈值,则方案可能会自动将数据从一个DataNode移动到另一个DataNode。在突然出现对特定文件的高需求的情况下,方案可能会动态地创建额外的副本,并重新平衡集群中的其他数据。这种类型的数据再平衡方案尚未实施。

数据完整性

存在这种可能,从DataNode获取的数据块到达时已损坏。这种损坏可能是由于存储设备故障、网络故障或有bug的软件造成的。HDFS客户端软件会对HDFS文件的内容进行校验和检查。当一个客户端创建了一个hdfs文件,从DataNode获取的数据块到达时可能已损坏。这种损坏可能是由于存储设备故障、网络故障或有bug的软件造成的。HDFS客户端软件对HDFS文件的内容进行校验和检查。当客户端查看文件内容时,它会验证从每个DataNode接收的数据是否与存储在关联校验和文件中的校验和相匹配。如果没有,那么客户端可以选择从拥有该块副本的另一个DataNode中检索该block块。

元数据失效

FsImage和EditLog是HDFS的核心数据结构。这些文件的损坏会导致HDFS实例失去作用。因此,NameNode可以配置为支持维护多个FsImage和EditLog副本。

任何对FsImage或EditLog的更新都会导致每个FsImage和EditLog同步更新。这种多个副本的同步更新可能会降低NameNode的命名空间的事务效率。但是,这种降级是可以接受的,因为尽管 HDFS 应用程序本质上是数据密集型的,但它们并不是元数据密集型的。 当 NameNode 重启时,它会选择最新一致的 FsImage 和 EditLog 来使用。

提高故障恢复能力的另一个选择是使用多个 NameNode来实现高可用,通过使用 NFS 上的共享存储 shared storage on NFS或使用分布式编辑日志distributed edit log(叫做Journal)来实现。 后者是推荐的方法。

快照

Snapshots 支持在特定时刻存储数据的副本。快照的一个可能用途是将损坏的HDFS实例回滚到之前已知的好的时间点。

数据组织
数据块

HDFS被设计成支持非常大的文件。与HDFS兼容的应用是那些处理大数据集的应用。这些应用程序只写入数据一次,但读取数据一次或多次,并且要求这些读取满足流的速度。

HDFS支持文件的write-once-read-many。HDFS的典型块大小是128mb。因此,一个HDFS文件会被切成128mb的块,如果可能,每个块将存储在不同的DataNode上。

副本的管道复制

当客户端向HDFS写入一个复制因子为3的文件时,NameNode使用replication target choosing algorithm副本目标选择算法来检索datanode列表,列表中的datanode将会各存储一个副本。首先列表中的第一个datanode会分部分来接收文件数据,并把接收到的每个部分存储到本地空间中,然后把这些portion传递给第二个DataNode;第二个DataNode依次接收第一个datanode传输过来的portion数据并持久化到本地空间,然后依次传输给第三个datanode,并被第三个datanode持久化到本地空间。以这种类似管道的形式来传输数据,从管道中的前一个datanode接收数据,同时将数据转发给管道中的下一个datanode。

访问方式

可以通过多种不同方式访问 HDFS。 HDFS 本身提供了一个 FileSystem Java API 供应用程序使用。 基于 C language wrapper for this Java API Java API 封装的C和 REST API REST API也可用。 此外,HTTP 浏览器也可用于浏览 HDFS 实例的文件。 通过使用 NFS gateway NFS 网关,HDFS 可以作为客户端本地文件系统的一部分,相当于一个代理,用户想要访问HDFS可以通过NFS来实现,通过NFS可以将HDFS上的目录挂载到本地当做本地目录来使用。。

FS Shell

HDFS 允许以文件和目录的形式组织用户数据。 它提供了一个名为 FS shell 的命令行界面,允许用户与 HDFS 中的数据进行交互。 此命令集的语法类似于其他 shell(例如 bash、csh)。 以下是一些示例操作:

ActionCommand
创建目录 /foodirbin/hadoop dfs -mkdir /foodir
移除目录 /foodirbin/hadoop fs -rm -R /foodir
查看文件内容/foodir/myfile.txtbin/hadoop dfs -cat /foodir/myfile.txt

FS shell适用于需要脚本语言来与存储的数据交互的应用程序。

DFS Admin

DFS Admin 命令集用于管理 HDFS 集群。 这些是仅供 HDFS 管理员使用的命令。 以下是一些示例操作:

ActionCommand
将集群设置为安全模式bin/hdfs dfsadmin -safemode enter
生成datanode列表bin/hdfs dfsadmin -report
退役或上线datanodebin/hdfs dfsadmin -refreshNodes
Browser Interface

HDFS的配置了TCP端口来暴露命名空间。这允许用户使用web浏览器浏览HDFS命名空间并查看其文件的内容。

空间回收
文件的删除和恢复

如果启用了trash配置,FS Shell 删除的文件不会立即从 HDFS 中删除。 相反,HDFS 将其移动到trash目录(每个用户在 /user//.Trash 下都有自己的trash目录)。 只要文件保留在trash中,就可以快速恢复该文件。

最近删除的文件移动到当前trash目录(/user//.Trash/Current)中。在一个固定的时间间隔内(可配置),HDFS 会为当前trash目录中的文件创建检查点(在 /user//.Trash/ 下),在过期时删除旧的检查点。有关trash检查点的信息,请参阅 FS shell 的 expunge 命令 expunge command of FS shell

当文件在trash中过期后,NameNode将文件从HDFS命名空间中删除。删除文件会释放与该文件关联的块。注意,在用户删除文件和HDFS中增加相应空闲空间之间可能存在一个明显的时间延迟。

降低副本因子

当文件的复制因子降低时,NameNode会选择多余的副本进行删除。NameNode在下一个Heartbeat中将此信息传输到DataNode。然后DataNode删除相应的block,集群增加对应的空闲空间。同样,在完成setReplication API调用和集群中出现空闲空间之间可能存在时间延迟。

未经授权请勿转载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值