本篇文章翻译了 Hadoop 系列下的 HDFS Architecture ,原文最初经过笔者翻译后大概有 6000 字,之后笔者对内容进行了精简化压缩,从而使笔者自己和其他读者们阅读本文时能够更加高效快速的完成对 Hadoop 的学习或复习。本文主要介绍了 Hadoop 的整体架构,包括但不限于节点概念、命名空间、数据容错机制、数据管理方式、简单的脚本命令和垃圾回收概念。
PS:笔者新手一枚,如果看出哪里存在问题,欢迎下方留言!
Hadoop Distributed File System(HDFS)是高容错、高吞吐量、用于处理海量数据的分布式文件系统。
HDFS 一般由成百上千的机器组成,每个机器存储整个数据集的一部分数据,机器故障的快速发现与恢复是 HDFS 的核心目标。
HDFS 对接口的核心目标是高吞吐量而非低延迟。
HDFS 支持海量数据集合,一个集群一般能够支持千万以上数量级的文件。
HDFS 应用需要对文件写一次读多次的接口模型,文件变更只支持尾部添加和截断。
HDFS 的海量数据与一致性接口特点,使得迁移计算以适应文件内容要比迁移数据从而支持计算更加高效。
HDFS 支持跨平台使用。
HDFS 使用主从架构。一个 HDFS 集群由一个 NameNode、一个主服务器(用于管理系统命名空间和控制客户端文件接口)、大量的 DataNode(一般一个节点一个,用于管理该节点数据存储)。HDFS 对外暴露了文件系统命名空间并允许在文件中存储用户数据。一个文件被分成一个或多个块,这些块存储在一组 DataNode 中。NameNode 执行文件系统命名空间的打开关闭重命名等命令并记录着块和 DataNode 之间的映射。DataNode 用于处理客户端的读写请求和块的相关操作。NameNode 和 DataNode 一般运行在 GNU/Linux 操作系统上,HDFS 使用 Java 语言开发的,因此 NameNode 和 DataNode 可以运行在任何支持 Java 的机器上,再加上 Java 语言的高度可移植性,使得 HDFS 可以发布在各种各样的机器上。一个 HDFS 集群中运行一个 NameNode,其他机器每个运行一个(也可以多个,非常少见)DataNode。NameNode 简化了系统的架构,只用于存储所有 HDFS 元数据,用户数据不会进入该节点。下图为 HDFS 架构图:
HDFS Architecture
HDFS 支持传统的分层文件管理,用户或者应用能够在目录下创建目录或者文件。文件系统命名空间和其他文件系统是相似的,支持创建、删除、移动和重命名文件。HDFS 支持用户数量限制和访问权限控制,不支持软硬链接,用户可以自己实现软硬链接。NameNode 控制该命名空间,命名空间任何变动几乎都要记录到 NameNode 中。应用可以在 HDFS 中对文件声明复制次数,这个次数叫做复制系数,会被记录到 NameNode 中。
HDFS 将每个文件存储为一个或多个块,并为文件设置了块的大小和复制系数从而支持文件容错。一个文件所有的块(除了最后一个块)大小相同,后来支持了可变长度的块。复制系数在创建文件时赋值,后续可以更改。文件在任何时候只能有一个 writer。NameNode 负责块复制,它周期性收到每个数据节点的心跳和块报告,心跳表示数据节点的正常运作,块报告包含了这个 DataNode 的所有块。
副本存储方案对于 HDFS 的稳定性和性能至关重要。为了提升数据可靠性、灵活性和充分利用网络带宽,HDFS 引入了机架感知的副本存储策略,该策略只是副本存储策略的第一步,为后续优化打下基础。大型 HDFS 集群一般运行于横跨许多支架的计算机集群中,一般情况下同一支架中两个节点数据传输快于不同支架。一种简单的方法是将副本存放在单独的机架上,从而防止丢失数据并提高带宽,但是增加了数据写入的负担。一般情况下,复制系数是 3,HDFS 存储策略是将第一份副本存储到本地机器或者同一机架下一个随机 DataNode,另外两份副本存储到同一个远程机架的不同 DataNode。NameNode 不允许同一 DataNode 存储相同副本多次。在机架感知的策略基础上,后续支持了 存储类型和机架感知相结合的策略 ,简单来说就是在机架感知基础上判断 DataNode 是否支持该类型的文件,不支持则寻找下一个。
HDFS 读取数据使用就近原则,首先寻找相同机架上是否存在副本,其次本地数据中心,最后远程数据中心。
启动时,NameNode 进入安全模式,该模式下不会发生数据块复制,NameNode 接收来自 DataNode 的心跳和块报告,每个块都有一个最小副本数量 n,数据块在 NameNode 接受到该块 n 次后,认为这个数据块完成安全复制。当完成安全复制的数据块比例达到一个可配的百分比值并再过 30s 后,NameNode 退出安全模式,最后判断是否仍然存在未达到最小复制次数的数据块,并对这些块进行复制操作。
NameNode 使用名为 EditLog 的事务日志持续记录文件系统元数据的每一次改动(如创建文件、改变复制系数),使用名为 FsImage 的文件存储全部的文件系统命名空间(包括块到文件的映射关系和文件系统的相关属性),EditLog 和 FsImage 都存储在 NameNode 本地文件系统中。NameNode 在内存中保存着元数据和块映射的快照,当 NameNode 启动后或者某个配置项达到阈值时,会从磁盘中读取 EditLog 和 FsImage,通过 EditLog 新的记录更新内存中的 FsImage,再讲新版本的 FsImage 刷新到磁盘中,然后截断 EditLog 中已经处理的记录,这个过程就是一个检查点。检查点的目的是确保文件系统通过在内存中使用元数据的快照从而持续的观察元数据的变更并将快照信息存储到磁盘 FsImage 中。检查点通过下面两个配置参数出发,时间周期(dfs.namenode.checkpoint.period)和文件系统事务数量(dfs.namenode.checkpoint.txns),二者同时配置时,满足任意一个条件就会触发检查点。
所有的 HDFS 网络协议都是基于 TCP/IP 的,客户端建立一个到 NameNode 机器的可配置的 TCP 端口,用于二者之间的交互。DataNode 使用 DataNode 协议和 NameNode 交互,RPC 包装了客户端协议和 DataNode 协议,通过设计,NameNode 不会发起 RPC,只负责响应来自客户端或者 DataNode 的 RPC 请求。
HDFS 的核心目标是即使在失败或者错误情况下依然能够保证数据可靠性,三种常见失败情况包括 NameNode 故障、DataNode 故障和 network partitions。
网络分区可能会导致部分 DataNode 市区和 NameNode 的连接,NameNode 通过心跳包判断并将失去连接的 DataNode 标记为挂掉状态,于是所有注册到挂掉 DataNode 的数据都不可用了,可能会导致部分数据块的复制数量低于了原本配置的复制系数。NameNode 不断地追踪哪些需要复制的块并在必要时候进行复制,触发条件包含多种情况:DataNode 不可用、复制乱码、硬件磁盘故障或者认为增大负值系数。为了避免 DataNode 的状态不稳定导致的复制风暴,标记 DataNode 挂掉的超时时间设置比较长(默认 10min),用户可以设置更短的时间间隔来标记 DataNode 为陈旧状态从而避免在对读写性能要求高的请求上使用这些陈旧节点。
HDFS 架构兼容数据各种重新平衡方案,一种方案可以在某个 DataNode 的空闲空间小于某个阈值时将数据移动到另一个 DataNode 上;在某个特殊文件突然有高的读取需求时,一种方式是积极创建额外副本并且平衡集群中的其他数据。这些类型的平衡方案暂时还未实现(不太清楚现有方案是什么...)。
存储设备、网络或者软件的问题都可能导致从 DataNode 获取的数据发生乱码,HDFS 客户端实现了对文件内容的校验,客户端在创建文件时,会计算文件中每个块的校验值并存储到命名空间,当客户端取回数据后会使用校验值对每个块进行校验,如果存在问题,客户端就会去另一个 DataNode 获取这个块的副本。
FsImage 和 EditLog 是 HDFS 的核心数据结构,他们的错误会导致整个 HDFS 挂掉,因此,NameNode 应该支持时刻维持 FsImage 和 EditLog 的多分复制文件,它们的任何改变所有文件应该同步更新。另一个选择是使用 shared storage on NFS 或者 distributed edit log 支持多个 NameNode,官方推荐 distributed edit log 。
快照能够存储某一特殊时刻的数据副本,从而支持 HDFS 在发生错误时会滚到上一个稳定版本。
HDFS 的应用场景是大的数据集下,且数据只需要写一次但是要读取一到多次并且支持流速读取数据。一般情况下一个块大小为 128MB,因此一个文件被切割成 128MB 的大块,且每个快可能分布在不同的 DataNode。
当客户端在复制系数是 3 的条件下写数据时,NameNode 通过目标选择算法收到副本要写入的 DataNode 的集合,第 1 个 DataNode 开始一部分一部分的获取数据,把每个部分存储到本地并转发给第 2 个 DataNode,第 2 个 DataNode 同样的把每个部分存储到本地并转发给第 3 个 DataNode,第 3 个 DataNode 将数据存储到本地,这就是管道复制。
HDFS 提供了多种访问方式,比如 FileSystem Java API 、 C language wrapper for this Java API 和 REST API ,而且还支持浏览器直接浏览。通过使用 NFS gateway ,客户端可以在本地文件系统上安装 HDFS。
HDFS 使用目录和文件的方式管理数据,并提供了叫做 FS shell 的命令行接口,下面有一些简单的命令:
FS shell sample
DFSAdmin 命令集合用于管理 HDFS 集群,这些命令只有集群管理员可以使用,下面有一些简单的命令:
DFSAdmin sample
正常的 HDFS 安装都会配置一个 web 服务,通过可配的 TCP 端口对外暴露命名空间,从而使得用户可以通过 web 浏览器查看文件内容。
如果垃圾回收配置打开,通过 FS shell 移除的文件不会立刻删除,而是会移动到一个垃圾文件专用的目录(/user/
FS shell delete sample
当文件复制系数减小时,NameNode 会选择多余的需要删除的副本,在收到心跳包时将删除信息发送给 DataNode。和上面一样,这个删除操作也是需要一些时间后,才能在集群上展现空闲空间的增加。
来源: http://www.jianshu.com/p/47da8a11b193