分布式文件系统:架构和设计简介
HDFS 是一个设计用于在通用硬件()上运行的分布式文件系统。它与现有的分布式文件系统有很多共同之处。但与此同时,它也与其他分布式文件系统有很大不同。HDFS 是一个高容错系统,适合部署在廉价的机器上。HDFS 可以提供高吞吐量的数据访问,非常适合大规模数据集上的应用程序。HDFS 放宽了一些 POSIX 约束,以达到流式传输文件系统数据的目的。HDFS 最初是作为 Nutch 搜索引擎项目的基础架构开发的。HDFS 是 Core 项目的一部分。这个项目的地址是。
先决条件和设计目标
硬件错误
硬件错误是常态,而不是例外。HDFS 可能由数百或数千台服务器组成,每台服务器都存储着文件系统的部分数据。我们面临的现实是,组成系统的组件数量庞大,任何一个组件都可能出现故障,这意味着总有一些 HDFS 组件无法正常工作。因此,错误检测和快速、自动恢复是 HDFS 的核心架构目标。
流数据访问
运行在HDFS上的应用程序与普通应用程序不同,需要流式访问其数据集。HDFS的设计考虑的是数据批处理,而不是用户交互处理。高数据访问吞吐量比低延迟更重要。POSIX标准设定的很多硬性约束对于HDFS应用系统来说并不是必要的。为了提高数据吞吐量,对POSIX的一些关键方面的语义进行了修改。
大规模数据集
在 HDFS 上运行的应用程序具有大型数据集。HDFS 上的典型文件大小通常在 GB 到 TB 范围内。因此,HDFS 经过调整以支持大文件存储。它应该提供较高的总体数据传输带宽,并能够扩展到集群中的数百个节点。单个 HDFS 实例应该能够支持数千万个文件。
简单一致性模型
HDFS 应用程序需要“一次写入,多次读取”的文件访问模型。一旦创建、写入和关闭文件,就不需要更改它。这种假设简化了数据一致性问题,并实现了高吞吐量数据访问。地图/应用程序或网络爬虫应用程序非常适合此模型。未来计划扩展此模型以支持对文件的其他写入操作。
“移动计算比移动数据更具成本效益”
应用程序请求的计算越靠近它操作的数据,效率就越高,尤其是在数据达到海量级别的情况下。因为这样可以减少网络拥塞的影响,提高系统数据的吞吐量。将计算移近数据显然比将数据移近应用程序更好。HDFS 为应用程序提供了一个接口,让应用程序将自己移近数据。
异构硬件和软件平台之间的可移植性
HDFS在设计时就充分考虑了平台的可移植性,有利于HDFS作为大规模数据应用平台的推广。
和
HDFS采用从/从架构,HDFS集群由一个和一定数量的节点组成,它是一个中央服务器,负责管理文件系统的命名空间()和客户端对文件的访问。集群中一般有一个节点,负责管理所在节点上的存储。HDFS将文件系统的命名空间暴露出来,用户可以以文件的形式在上面存储数据。在内部,一个文件实际上被分成一个或多个数据块,数据块以组的形式存储。执行文件系统命名空间操作,比如打开、关闭和重命名文件或目录。还负责确定数据块到具体节点的映射。负责处理来自文件系统客户端的读写请求。在统一的调度下创建、删除和复制数据块。
HDFS 旨在运行在常见的商用机器上。这些机器通常运行 GNU/Linux 操作系统 (OS)。HDFS 是用 Java 开发的,因此任何支持 Java 的机器都可以部署或运行。由于 Java 语言具有高度的可移植性,HDFS 可以部署在许多类型的机器上。典型的部署场景是一台机器上只运行一个实例,集群中的其他机器各运行一个实例。这种架构并不排除在一台机器上运行多个实例,但这种情况很少见。
集群中的单一结构大大简化了系统架构,它是所有HDFS元数据的仲裁者和管理者,使得用户数据永不流动。
文件系统命名空间()
HDFS支持传统的层次化文件组织结构,用户或者应用程序可以创建目录,然后将文件存储在这些目录中。文件系统命名空间的层次结构与大多数现有的文件系统类似:用户可以创建、删除、移动或重命名文件。目前,HDFS不支持用户磁盘配额和访问控制,也不支持硬链接和软链接。但HDFS的架构并不妨碍这些特性的实现。
负责维护文件系统命名空间。对文件系统命名空间或属性的任何更改都将被记录。应用程序可以设置存储在 HDFS 中的文件副本数。文件副本数称为文件的复制因子,此信息也会被保存。
数据复制
HDFS 旨在可靠地跨大型集群中的机器存储超大文件。它将每个文件存储为一系列数据块,除最后一个数据块外,所有数据块的大小都相同。为了实现容错,文件的所有数据块都会被复制。每个文件的块大小和复制因子都是可配置的。应用程序可以指定文件的副本数。复制因子可以在创建文件时指定,并可在以后更改。HDFS 中的文件是一次写入的,并且严格要求任何时候只能有一个写入者。
节点管理数据块的复制,它定期从集群中的各个节点接收心跳信号和块状态报告()。收到心跳信号表示节点正常工作。块状态报告包含节点上所有数据块的列表。
副本存储:第一步
副本的存储是 HDFS 可靠性和性能的关键。优化的副本存储策略是 HDFS 区别于大多数其他分布式文件系统的重要特性。该特性需要大量的调优和经验积累。HDFS 使用一种称为 rack- 的策略来提高数据的可靠性、可用性和网络带宽利用率。当前实现的副本存储策略只是朝这个方向迈出的第一步。实现该策略的短期目标是在生产环境中验证其有效性,观察其行为,为实现更高级的策略奠定测试和研究基础。
大型HDFS实例通常运行在跨多个机架的计算机集群上,不同机架上的两台机器之间的通信需要通过交换机,大多数情况下同一机架上的两台机器之间的带宽大于不同机架上的两台机器之间的带宽。
通过一个流程,可以确定各自的rack id。一个简单但不优化的策略是将副本存放在不同的rack上。这样可以有效防止整个rack故障时数据丢失,同时在读取数据时可以充分利用多个rack的带宽。这种策略设置可以使副本在集群中均匀分布,有利于组件故障时的负载均衡。但是由于这种策略的一次写入操作需要将数据块传输到多个rack上,因此增加了写入的成本。
多数情况下复制因子为3,HDFS的存储策略是在本机架的节点上存储一个副本,在同一机架的另一个节点上存储一个副本,最后一个副本在不同机架的节点上存储。这种策略减少了机架之间的数据传输,提高了写操作的效率。机架错误远少于节点错误,因此这种策略不会影响数据的可靠性和可用性。同时由于数据块只放在两个(而不是三个)不同的机架上,所以这种策略减少了读取数据时所需的总网络传输带宽。这种策略下,副本并不是均匀分布在不同的机架上的,三分之一的副本在一个节点上,三分之二的副本在一个机架上,其他的副本均匀分布在剩下的机架上。这种策略在不损害数据可靠性和读性能的情况下提高了写性能。
目前,这里描述的默认副本放置策略正在开发中。
复制选择
为了减少总体带宽消耗和读取延迟,HDFS 会尝试让读取器读取距离自己最近的副本。如果在与读取器相同的机架上有副本,则读取该副本。如果 HDFS 集群跨越多个数据中心,客户端也会首先读取本地数据中心的副本。
安全模式
启动之后会进入一个特殊的状态,称为安全模式。安全模式下,数据块不会被复制。会接收来自各方的心跳信号和块状态报告。块状态报告包括所有数据块的列表。每个数据块都有指定的最小副本数,当检测确认某个数据块的副本数达到这个最小值时,该数据块将被认为是复制安全的();在检测到一定比例(这个参数可配置)的数据块并确认是安全的(加上额外的30秒等待时间)后,将退出安全模式状态。接下来它会判断哪些数据块没有达到指定的副本数,把这些数据块复制给其他人。
文件系统元数据的持久性
HDFS 命名空间存储在 上。任何修改文件系统元数据的操作都会使用名为 的事务日志进行记录。例如,在 HDFS 中创建一个文件时,会向 中插入一条记录;同样,当修改文件的副本系数时,会向 中插入一条记录。这存储在本地操作系统的文件系统中。整个文件系统的命名空间,包括数据块到文件的映射、文件属性等,都存储在名为 的文件中,该文件也放在本地文件系统上。
整个文件系统名称空间和文件数据块映射()的映像存储在内存中。这个关键元数据结构设计得紧凑,因此 4G 内存足以支持大量文件和目录。启动时,它会从硬盘读取并执行,将内存中的所有事务应用到新版本,将新版本从内存保存到本地磁盘,然后删除旧版本,因为旧事务已经应用于它。这个过程称为检查点()。在目前的实现中,检查点仅在启动时发生,在不久的将来将实现对定期检查点的支持。
HDFS 数据以文件的形式存储在本地文件系统中,它并不知道 HDFS 文件的信息,它将每个 HDFS 数据块存储在本地文件系统的单独文件中。它不会将所有文件都创建在同一个目录中,事实上,它使用启发式方法来确定每个目录的最佳文件数,并在适当的时候创建子目录。将所有本地文件都创建在同一个目录中并不是最好的选择,因为本地文件系统可能无法高效地支持单个目录中的大量文件。当 a 启动时,它会扫描本地文件系统,生成这些本地文件对应的所有 HDFS 数据块的列表,然后将其作为报告发送给 a,该报告即块状态报告。
协议
HDFS 所有的通信协议都建立在 TCP/IP 协议之上,客户端通过可配置的 TCP 端口连接到 Disk ,通过协议与其进行交互。协议中抽象出一个远程过程调用(RPC)模型进行封装。在设计上, Disk 不会主动发起 RPC,而是响应客户端或者客户端发送的 RPC 请求。
鲁棒性
HDFS 的主要目标是确保即使发生错误也能可靠地存储数据。最常见的三种错误情况是:错误、错误和网络分区()。
磁盘数据错误、心跳检测和重新复制
每个节点都会定期向节点发送心跳信号。网络分裂可能会导致某些节点失去联系。这种情况通过缺少心跳信号来检测,那些近期不再发送心跳信号的节点被标记为宕机,不会向其发送新的 IO 请求。宕机时存储的任何数据都将不再有效。宕机可能会导致某些数据块的复制系数低于指定值。节点不断检测这些需要复制的数据块,一旦发现,就启动复制操作。在以下情况下可能需要重新复制:节点故障、副本损坏、节点上的硬盘错误或文件的复制系数增加。
集群平衡
HDFS 的架构支持数据平衡策略。如果某个节点上的可用空间低于某个临界点,系统将根据平衡策略自动将数据从该节点移动到其他可用节点。当对某个文件的请求突然增加时,还可能会启动一个计划来创建该文件的新副本并同时重新平衡集群中的其他数据。这些平衡策略尚未实现。
数据的完整性
从某个文件获取的数据块可能会损坏,这可能是由于存储设备错误、网络错误或者软件 Bug 造成的。HDFS 客户端软件对 HDFS 文件内容实现了 () 校验。客户端在创建一个新的 HDFS 文件时,会计算该文件每个数据块的校验和,并将校验和作为单独的隐藏文件保存在同一个 HDFS 命名空间中。客户端在获取文件内容时,会检查获取的数据中的校验和是否与对应校验和文件中的校验和匹配,如果不匹配,客户端可以选择从其他来源获取该数据块的副本。
元数据磁盘错误
sum 是 HDFS 的核心数据结构,如果这些文件损坏,整个 HDFS 实例就会失败。因此可以配置支持维护 sum 的多个副本,对 或 的任何修改都会同步到它们的副本上。这种对多个副本的同步可能会减少每秒处理的命名空间事务数量。不过这个代价是可以接受的,因为即使 HDFS 应用程序是数据密集型的,它们也不是元数据密集型的。在重新启动时,它会选择最近完成的 sum 来使用。
是HDFS集群中的单点故障,如果机器发生故障,需要人工干预,目前没有实现自动重启或者故障转移到另一台机器。
快照
快照支持在特定时刻复制和备份数据。使用快照,当数据损坏时,HDFS 可以恢复到过去已知的正确时间点。HDFS 目前不支持快照功能,但计划在未来版本中支持该功能。
数据组织
数据块
HDFS 被设计为支持大文件。它适用于需要处理大规模数据集的应用程序。这些应用程序只写入一次数据,但读取一次或多次,读取速度应该能够满足流式读取的需求。HDFS 支持文件的“一次写入,多次读取”语义。一个典型的数据块大小为 64MB。因此,HDFS 中的文件总是按照 64M 被分成不同的块,每个块中尽可能存储不同的数据。
客户端创建文件的请求实际上并不是立即发送的,实际上在初始阶段,HDFS客户端会先把文件数据缓存到一个本地的临时文件中,应用程序的写操作被透明地重定向到这个临时文件,当这个临时文件中积累的数据量超过一个数据块的大小时,客户端就会将文件名插入到文件系统的层次结构中,并为其分配一个数据块。然后将标识符和目标数据块返回给客户端。客户端随后将这块数据从本地临时文件中上传到指定的文件中。当文件关闭时,临时文件中剩余的还未上传的数据也会转移到指定的文件中。然后客户端告知文件已经关闭。这时才将文件创建操作提交到日志中进行存储。如果在文件关闭之前系统崩溃,则文件将会丢失。
上述方法是经过仔细考虑运行在 HDFS 上的目标应用程序的结果。这些应用程序需要流式传输文件。如果没有客户端缓存,网络速度和网络拥塞将对吞吐量产生重大影响。这种方法并非没有先例。早期的文件系统,如 AFS,使用客户端缓存来提高性能。为了实现更高的数据上传效率,POSIX 标准的要求已经放宽。
管道复制
当客户端向HDFS文件写入数据时,会先写入本地临时文件,假设该文件的复制因子设置为3,当本地临时文件积累到一个数据块大小时,客户端会获得一个列表,从中存储副本。然后客户端开始向第一个节点传输数据,第一个节点以小块(4KB)接收数据,将每块写入本地仓库,同时将该块传输给列表中的第二个节点。第二个节点也一样,以小块接收数据,写入本地仓库,同时传输给第三个节点。最后第三个节点接收数据并存储到本地。因此,可以以流水线的方式从上一个节点接收数据,同时转发到下一个节点,数据以流水线的方式从上一个节点复制到下一个节点。
无障碍设施
HDFS为应用程序提供了多种访问方式,用户可以通过Java API接口、C语言封装的API或者浏览器访问,协议访问方式正在开发中。
HDFS 以文件和目录的形式组织用户数据,提供命令行界面(CLI)供用户与 HDFS 中的数据交互,命令语法与用户熟悉的其他 shell 工具(如 bash、csh)类似,以下是一些操作/命令的示例:
动作命令
创建一个名为 / 的目录
宾/dfs-mkdir/
创建一个名为 / 的目录
宾/dfs-mkdir/
查看名为 //.txt 的文件的内容
bin/dfs-cat //.txt
可用于通过脚本语言与文件系统交互的应用程序。
命令用于管理 HDFS 集群。这些命令只能由 HDFS 管理员使用。以下是一些操作/命令的示例:
动作命令
将集群置于安全模式
bin/-输入
显示列表
垃圾桶/ -
退役节点
垃圾桶/ -
浏览器界面
典型的 HDFS 安装会在可配置的 TCP 端口上打开一个 Web 服务器,以公开 HDFS 命名空间。用户可以使用浏览器浏览 HDFS 命名空间并查看文件的内容。
存储空间回收
删除和恢复文件
当用户或应用程序删除文件时,文件不会立即从 HDFS 中删除。实际上,HDFS 会重命名文件并将其移动到 /trash 目录。只要文件仍在 /trash 目录中,就可以快速恢复。文件保留在 /trash 中的时间是可配置的。超过此时间后,文件将从命名空间中删除。删除文件将释放与该文件关联的数据块。请注意,用户删除文件和 HDFS 中可用空间增加之间会有一定的延迟。
只要被删除的文件还在/trash目录中,用户就可以恢复该文件。如果用户想要恢复被删除的文件,他/她可以浏览/trash目录来检索该文件。/trash目录只存储被删除文件的最后一个副本。/trash目录与其他目录没有什么不同,只是HDFS应用了一种特殊的策略来自动删除此目录中的文件。当前的默认策略是删除/trash中超过6小时的文件。将来,此策略将通过定义良好的接口进行配置。
减少副本数
当某个文件的副本数减少时,会选择删除多余的副本。此信息会传递到下一次心跳检测。然后删除相应的数据块,集群中的可用空间就会增加。同样,API 调用结束和集群中可用空间增加之间也会有一定的延迟。
参考
HDFS Java API:
HDFS源代码:
扫一扫在手机端查看
我们凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求,请立即点击咨询我们或拨打咨询热线: 13761152229,我们会详细为你一一解答你心中的疑难。