本文档的目标是为 Hadoop 分布式文件系统(HDFS)的用户提供一个学习的起点,这里的 HDFS 既可以作为 Hadoop 集群的一部分,也可以作为一个独立的分布式文件系统。虽然 HDFS 在很多环境下被设计成是可正确工作的,但是了解 HDFS 的工作原理对在特定集群上改进 HDFS 的运行性能和错误诊断都有极大的帮助。
HDFS 是 Hadoop 应用用到的一个最主要的分布式存储系统。一个 HDFS 集群主要由一个 NameNode 和很多个 Datanode 组成:Namenode 管理文件系统的元数据,而 Datanode 存储了实际的数据。HDFS 的体系结构在这里有详细的描述。本文档主要关注用户以及管理员怎样和 HDFS 进行交互。HDFS 架构设计中的图解描述了 Namenode、Datanode 和 客户端 之间的基本的交互操作。基本上,客户端联系 Namenode 以获取文件的元数据或修饰属性,而真正的文件 I/O 操作是直接和 Datanode 进行交互的。
下面列出了一些多数用户都比较感兴趣的重要特性。
下面列出的是 HDFS 中常用特性的一部分:
下面的文档描述了如何安装和搭建Hadoop集群:
文档余下部分假设用户已经安装并运行了至少包含一个 Datanode 节点的 HDFS。就本文目的来说,Namenode 和 Datanode 可以运行在同一个物理主机上。
NameNode 和 DataNode 各自启动了一个内置的 Web 服务器,显示了集群当前的基本状态和信息。在默认配置下 NameNode 的首页地址是 http://namenode-name:50070/。这个页面列出了集群里的所有 DataNode 和集群的基本状态。这个 Web 接口也可以用来浏览整个文件系统(使用 NameNode 首页上的 “Browse the file system” 链接)。
Hadoop 包括一系列的类 shell 的命令,可直接和 HDFS 以及其他 Hadoop 支持的文件系统进行交互。bin/hadoop fs -help
命令列出所有 Hadoop Shell 支持的命令。而 bin/hadoop fs -help command-name
命令能显示关于某个命令的详细信息。这些命令支持大多数普通文件系统的操作,比如复制文件、改变文件权限等。它还支持一些 HDFS特有的操作,比如改变文件副本数目。
'bin/hadoop dfsadmin'
命令支持一些和 HDFS 管理相关的操作。bin/hadoop dfsadmin -help
命令能列出所有当前支持的命令。比如:
NameNode 将对文件系统的改动追加保存到本地文件系统上的一个日志文件(edits)。当一个 NameNode 启动时,它首先从一个映像文件(fsimage)中读取 HDFS 的状态,接着应用日志文件中的 edits 操作。然后它将新的 HDFS 状态写入(fsimage)中,并使用一个空的 edits 文件开始正常操作。因为 NameNode 只有在启动阶段才合并 fsimage 和 edits,所以久而久之日志文件可能会变得非常庞大,特别是对大型的集群。日志文件太大的另一个副作用是下一次 NameNode 启动会花很长时间。
Secondary NameNode 定期合并 fsimage 和 edits 日志,将 edits 日志文件大小控制在一个限度下。因为内存需求和 NameNode 在一个数量级上,所以通常 secondary NameNode 和 NameNode 运行在不同的机器上。Secondary NameNode 通过 bin/start-dfs.sh
在 conf/masters
中指定的节点上启动。
Secondary NameNode 的检查点进程启动,是由两个配置参数控制的:
Secondary NameNode 存储最新的检查点,它目录结构与主 NameNode 一致,所以这个备用的检查点映像在主 NameNode 需要时,总是能访问的。
NameNode 采用两个文件来保存命名空间的信息:fsimage,它是最新的已执行检查点的命名空间的信息;edits,它是执行检查点后命名空间变化的日志文件。当 NameNode 启动时,fsimage 和 edits合并,提供一个最新的文件系统的 metadata,然后 NameNode 将新的 HDFS 状态写入 fasimage,并开始一个新的 edits 日志。
Checkpoint 节点周期性地创建命名空间的检查点。它从 NameNode 下载 fsimage 和 edits,在本地合并它们,并将其发回给 active 的 NameNode。Checkpoint 节点通常与 NameNode 不在同一台机器上,因为它们有同样的内存要求。Checkpoint 节点由配置文件中的 bin/hdfs namenode –checkpoint
来启动。
Checkpoint (或 Backup )节点的位置以及附带的 web 接口由 dfs.namenode.backup.address anddfs.namenode.backup.http-address 参数指定。
Checkpoint 进程的运行受两个配置参数控制:
Checkpoint 节点上保存的最新的检查点,其目录结构与 NameNode 上一样,这样,如果需要,NameNode 总是可以读取这上面的已执行检查点的文件映像。参见“import checkpoint”。
多个 Checkpoint 节点可以在集群的配置文件中指定。
Backup 节点与 Checkpoint 节点提供同样的执行检查点功能,只不过它还在内存中保存一份最新的命名空间的的拷贝,该拷贝与 NameNode 中的保持同步。除了接收 NameNode 中发送的 edits 并把它保存到磁盘之外,Backup 还将 edits 用到自己的内存中,因而创建出一份命名空间的备份。
因为 Backup 节点在内存中保持有最新的命名空间的状态,因此它不需要从 NameNode 下载 fsimage 和 edits 文件来创建一个检查点,而这是 Checkpoint 节点或 Secondary NameNode 所必需的步骤。Backup 节点的检查点进程更高效,因为它只需要将命名空间信息保存到本地的 fsimage 文件并重置 edits 就可以了。
由于 Backup 节点内存中维护了一份命名空间的拷贝,它的内存要求与 NameNode 一致。
NameNode 同一时刻只支持一个 Backup 节点。如果 Backup 在用,则不能注册 Checkpont 节点。同时有多个 Backup 节点会在将来被支持
Backup 节点的配置与 Checkpoint 节点一样,它采用 bin/hdfs namenode –backup
启动。Backup (或 Checkup )节点的位置及其 web 接口由配置参数 dfs.namenode.backup.address 和 dfs.namenode.backup.http-address 指定。
使用 Backup 节点,NameNode 就可以选择不进行存储,而将保持命名空间状态的责任交给 Backup 节点。为此,在 NameNode 的配置中,采用选项 -importCheckpoint
来启动 NameNode,并且不设置 edits 的存储位置选项 dfs.namenode.edits.dir
。
关于创建 Backup 和 Checkpoint 节点背后动机的详细讨论,请参见 HADOOP-4539。
如果其它所有的映像文件和 edits 都丢失了,可以将最后的检查点导入到 NameNode,为此,需要以下步骤:
-importCheckpoint
选项来启动 NameNodeNameNode 将从 dfs.namenode.checkpoint.dir 设置的目录中上载检查点,并将其保存在 dfs.namenode.name.dir 指定的目录中。如果 dfs.namenode.name.dir 中存在一个合法的映像文件,NameNode 就会启动失败,NameNode 要验证 dfs.namenode.checkpoint.dir 中的映像文件是否合法,但在任何情况下,都不会修改该文件。
HDFS 的数据不可能总是在 DataNode 中均匀分布。一个最常见的原因是因为有新的 DataNode 加入。当存放新数据块(文件是以一系列数据来保存的)时,NameNode 会考虑各种参数来选择 DataNode 接收该数据块,以下是一些这样的考虑:
基于多种考虑,DataNode 上的数据可能会不平衡,HDFS 为管理者提供了一个分析和再平衡数据的工具。一个简要的管理者指南的 PDF 附在 HADOOP-1652 中。
通常,大型 Hadoop 集群是以机架的形式来组织的,同一个机架上不同节点间的网络状况比不同机架之间的更为理想。另外,NameNode 设法将数据块副本保存在不同的机架上以提高容错性。Hadoop 允许集群的管理员通过配置 dfs.network.script 参数来确定节点所处的机架。当这个脚本配置完毕,每个节点都会运行这个脚本来获取它的机架 ID。默认的安装假定所有的节点属于同一个机架。这个特性及其配置参数在 HADOOP-692 所附的 PDF 上有更详细的描述。
NameNode 启动时会从 fsimage 和 edits 日志文件中装载文件系统的状态信息,接着它等待各个 DataNode 向它报告它们各自的数据块状态,这样,NameNode 就不会过早地开始复制数据块,即使在副本充足的情况下。这个阶段,NameNode 处于安全模式下。NameNode 的安全模式本质上是 HDFS 集群的一种只读模式,此时集群不允许任何对文件系统或者数据块修改的操作。通常 NameNode 会在开始阶段自动地退出安全模式。如果需要,你也可以通过 bin/hadoop dfsadmin -safemode
命令显式地将 HDFS 置于安全模式。NameNode 首页会显示当前是否处于安全模式。关于安全模式的更多介绍和配置信息请参考 JavaDoc:setSafeMode()。
HDFS 支持 fsck 命令来检查系统中的各种不一致状况。这个命令被设计来报告各种文件存在的问题,比如文件缺少数据块或者副本数目不够。不同于在本地文件系统上传统的 fsck 工具,这个命令并不会修正它检测到的错误。一般来说,NameNode 会自动修正大多数可恢复的错误。HDFS 的 fsck 不是一个 Hadoop shell 命令。它通过 bin/hadoop fsck
执行。 命令的使用方法请参考 fsck 命令 fsck 可用来检查整个文件系统,也可以只检查部分文件。
HDFS 支持 fetchdt 命令来获取授权标识,并将其存储在本地文件系统的一个文件中。以后,一个“非安全”的客户端可以用这个标识以后来访问受限的服务器(例如 NameNode)。获取这个标识,采用 RPC 或 HTTPS(over Kerberos) 方式,然后,在获取之前需要提交 Kerberos 凭证(运行 kinit 来获得凭证)。HDFS fechedt 命令不是一个 Hadoop shell 命令。它以 bin/hadoop fetchdt DTfile
方式运行。当你获得授权标识后,通过指定环境变量 HADOOP_TOKEN_FILE_LOCATION
为授权标识文件名,你就可以运行 HDFS 命令,而不需要 Kerberros 凭证了。
通常,你要配置多个 metadata 存储位置,当一个存储位置崩溃后,你可以从其它位置读取到 metadata。
但是,如果仅有的一个存储位置崩溃后怎么办呢?在这种情况下,有一个特别的 NameNode 启动模式,叫恢复模式,允许你恢复大大部分数据。
你可以像这样启动恢复模式:namenode –recover
在恢复模式时,NameNode 以命令行的方式与你交互,显示你可能采取的恢复数据的措施。
如果你不想采用交互模式,你可以加上选项 -force
,这个选项将强制选取第一个选择恢复,通常,这是最合理的选择。
由于恢复模式可能使数据丢失,你应该在使用它之前备份 edit 日志文件和 fsimage。
当在一个已有集群上升级 Hadoop 时,像其他的软件升级一样,可能会有新的 bug 或一些会影响到现有应用的非兼容性变更出现。在任何有实际意义的 HDSF 系统上,丢失数据是不被允许的,更不用说重新搭建启动 HDFS 了。HDFS 允许管理员退回到之前的 Hadoop 版本,并将集群的状态回滚到升级之前。更多关于 HDFS 升级的细节在升级 wiki 上可以找到。HDFS 在一个时间可以有一个这样的备份。在升级之前,管理员需要用 bin/hadoop dfsadmin -finalizeUpgrade
(升级终结操作)命令删除存在的备份文件。下面简单介绍一下一般的升级过程:
dfsadmin -upgradeProgress status
命令能够知道是否需要对一个集群执行升级终结操作-upgrade
选项运行新的版本(bin/start-dfs.sh -upgrade)When upgrading to a new version of HDFS, it is necessary to rename or delete any paths that are reserved in the new version of HDFS. If the NameNode encounters a reserved path during upgrade, it will print an error like the following:
/.reserved is a reserved path and .snapshot is a reserved path component in this version of HDFS. Please rollback and delete or rename this path, or upgrade with the -renameReserved [key-value pairs] option to automatically rename these paths during upgrade.
Specifying -upgrade -renameReserved [optional key-value pairs] causes the NameNode to automatically rename any reserved paths found during startup. For example, to rename all paths named .snapshot to .my-snapshot and .reserved to .my-reserved, a user would specify -upgrade -renameReserved .snapshot=.my-snapshot,.reserved=.my-reserved.
If no key-value pairs are specified with -renameReserved, the NameNode will then suffix reserved paths with ..UPGRADE_RENAMED, e.g. .snapshot.-51.UPGRADE_RENAMED.
There are some caveats to this renaming process. It’s recommended, if possible, to first hdfs dfsadmin -saveNamespace before upgrading. This is because data inconsistency can result if an edit log operation refers to the destination of an automatically renamed file.
文件的权限设计地类似于其它类平台,如 Linux。目前,安全还限制在简单的文件权限方面。启动 NameNode 的用户被 HDFS 视为超级用户。HDFS 的以后版本将支持网络安全协议,例如 Kerberos,来做用户安全认证和加密数据传输,详细的讨论见权限指南。
Hadoop 目前可以运行在由上千个节点组成的集群上。Wiki 页上列出了一些采用大集群的组织。每个集群有一个NameNode。目前NameNode上可用的总内存数量是一个扩展性的基本限制。在非常巨大的集群上,增加存储在HDFS上文件的平均大小,有助于增加整个集群的尺寸而不会增加NameNode上内存的使用量,缺省的配置可能不适合非常巨大的集群,Wike页列出了在大集群情况下为提供性能而建议的配置项。
本文档的目标是为 Hadoop 分布式文件系统(HDFS)的用户提供一个学习的起点。尽管用户手册继续改进,但仍然有很多关于 Hadoop 和 HDFS 的文档。以下救列举了一系列关于未来探索的学习点: