命名空间的持久化
HDFS名称空间由NameNode存储。 NameNode使用名为EditLog的事务日志来持久记录文件系统元数据发生的每一个变化。 例如,在HDFS中创建一个新文件会产生NameNode向EditLog中写入一条记录,记录这一点。同样,复制因子更改文件会导致将新记录写入到EditLog中。 NameNode使用其本地主机OS文件系统中的文件来存储EditLog。 整个文件系统名称空间(包括块到文件和文件系统属性的映射)存储在一个名为FsImage的文件中。 FsImage也作为文件存储在NameNode的本地文件系统中。
NameNode将整个文件系统命名空间和文件Blockmap的映像保存在内存中。当NameNode启动时,或者一个检查点被一个可配置的阈值触发时,它从磁盘读取FsImage和EditLog,将EditLog中的所有事务应用到FsImage的内存中进行表示,并将这个新版本FsImage刷新到磁盘上。 它可以截断旧的EditLog,因为它的事务已经被应用到持久化的FsImage,这个过程被称为检查点。 检查点的目的是通过拍摄文件系统元数据的快照并将其保存到FsImage来确保HDFS具有文件系统元数据的一致视图。即使读取FsImage是有效的,直接对FsImage进行增量编辑也是无效的。 我们没有为每个编辑(改变)修改FsImage,而是将编辑(改变)保存在Editlog中。 在检查点期间,来自Editlog的更改将应用于FsImage。 一个检查点可以在一个给定的以秒表示的时间间隔( dfs.namenode.checkpoint.period ),或者在满足给定数目的文件系统事务累积( dfs.namenode.checkpoint.txns )之后触发。 如果这两个属性都已设置,则要达到的第一个阈值将触发一个检查点。
DataNode将HDFS数据存储在本地文件系统的文件中。 DataNode没有关于HDFS文件的知识(信息)。 它将每个HDFS数据块存储在本地文件系统中的单独文件中。DataNode不会在同一目录中创建所有文件。相反,它使用启发式来确定每个目录的最佳文件数量并适当地创建子目录。由于本地文件系统可能无法有效地支持单个目录中的大量文件,因此在同一目录中创建所有本地文件并不是最佳选择。 当DataNode启动时,它扫描本地文件系统,生成与这些本地文件相对应的所有HDFS数据块的列表,并将该报告发送给NameNode。 该报告被称为Blockreport 。
通信协议
所有的HDFS通信协议都是基于TCP / IP协议的。 客户端建立到NameNode机器上的可配置TCP端口的连接。 它与NameNode协商ClientProtocol。 DataNode使用协商的协议与NameNode进行通信。 远程过程调用(RPC)抽象包装客户端协议和数据节点协议。 根据设计,NameNode永远不会启动任何RPC。 而是只响应由DataNode或客户端发出的RPC请求。
稳健性
HDFS的主要目标是即使在出现故障时也能可靠地存储数据。 三种常见的故障类型是NameNode丢失,DataNode故障和网络割裂。
数据磁盘故障,心跳和重新复制
每个DataNode定期向NameNode发送一个Heartbeat(心跳)消息。 网络割裂可能导致DataNode的一个子集失去与NameNode的连接。 NameNode通过是否缺少Heartbeat消息来检测这种情况。 NameNode将最近没有发送Heartbeats的DataNode标记为死亡,并且不会将任何新的IO请求转发给它们。 任何已经注册到死亡的DataNode的数据不再可用于HDFS。 DataNode死亡可能导致某些块的复制因子降到其指定值以下。 NameNode不断跟踪哪些块需要复制,并在需要的时候启动复制。 重新复制的必要性可能由于许多原因而产生:DataNode可能变得不可用,副本可能被损坏,DataNode上的硬盘可能失败,或者文件的复制因子可能增加。
为了避免由于DataNode的状态动荡而导致的复制风暴(大量的复制),标记DataNode死的超时时间过于保守(默认超过10分钟)。 用户可以设置较短的时间间隔以将DataNode标记为陈旧,并避免在读取或按配置写入性能敏感的工作负载时过时的节点。
群集重新平衡
HDFS的架构兼容数据重新平衡方案。如果DataNode上的可用空间低于某个阈值,则方案可能会自动将数据从一个DataNode移动到另一个DataNode。 在特定文件突然高需求访问的情况下,这个方案可能会动态创建额外的副本并重新平衡群集中的其他数据。这些类型的数据重新平衡方案尚未实施。
数据的完整性
从DataNode获取的数据块可能会损坏。由于存储设备故障,网络故障或软件错误,可能会发生此损坏。HDFS客户端软件对HDFS文件的内容进行校验。当客户端创建一个HDFS文件时,它会计算每个文件块的校验和,并将这些校验和存储在同一个HDFS名称空间的单独隐藏文件中。当客户端检索文件内容时,它会验证从每个DataNode收到的数据是否与存储在相关校验和文件中的校验和相匹配。如果没有,那么客户端可以选择从另一个具有该块副本的DataNode中检索该块。
元数据磁盘失败
FsImage和EditLog是HDFS的核心数据结构。 这些文件的损坏可能会导致HDFS实例无法正常运行。为此,NameNode可以配置为支持维护FsImage和EditLog的多个副本。 任何对FsImage或EditLog的更新都会导致每个FsImages和EditLogs同步更新。 同步更新FsImage和EditLog的多个副本可能会降低NameNode每秒可支持的名称空间事务的速度。 但是,这种速度降低是可以接受的,因为即使HDFS应用程序本质上是非常密集的数据,它们也不是元数据密集型的。当NameNode重新启动时,它会选择最新的一致的FsImage和EditLog来使用。
另一个增强弹性以抵御故障的方法是使用多个NameNode启用高可用性,或者使用NFS上的共享存储或使用分布式编辑日志 (称为日志)。 后者是推荐的方法。
快照
快照支持在特定时刻存储数据副本。 快照功能的一种用法可能是将损坏的HDFS实例回滚到先前已知的良好时间点。
数据组织
数据块
HDFS旨在支持非常大的文件。 与HDFS兼容的应用程序是处理大型数据集的应用程序。这些应用程序只写入其数据一次,但是它们读取一次或多次,并要求以流速度满足这些读取。 HDFS支持在文件上一次写入多次读取语义。 HDFS使用的典型块大小为128 MB。 因此,一个HDFS文件被分成128 MB大小的块,如果可能的话,每个块将驻留在不同的DataNode上。
复制流水线
当客户端将数据写入复制因子为3的HDFS文件时,NameNode使用复制目标选择算法检索DataNode列表。 该列表包含将承载该块的副本的DataNode。 客户端然后写入第一个DataNode。 第一个DataNode开始接收部分数据,将每个部分写入其本地存储库,并将该部分传输到列表中的第二个DataNode。 第二个DataNode接着开始接收数据块的每个部分,将该部分写入其存储库,然后将该部分刷新到第三个DataNode。 最后,第三个DataNode将数据写入其本地存储库。 因此,DataNode可以从流水线中的前一个接收数据,同时将数据转发到流水线中的下一个。 因此,数据从一个DataNode流水线化到下一个。
可访问性
应用程序可以通过不同的方式对HDFS进行访问。 从本质上讲,HDFS为应用程序提供了一个FileSystem Java API(java的文件系统API) 。 此Java API的C语言封装和REST API也可用。另外还有一个HTTP输出进行浏览,也可以用来浏览HDFS实例的文件。 通过使用NFS网关 ,可以将HDFS作为客户端本地文件系统的一部分安装。
FS shell
HDFS允许用户数据以文件和目录的形式进行组织。它提供了一个名为FS shell的命令行界面,让用户可以与HDFS中的数据进行交互。 这个命令集的语法类似于用户已经熟悉的其他shell(例如bash,csh)。 以下是一些示例操作(命令对):
| 行动 | 命令 |
|---|---|
| 创建一个名为/ foodir的目录 |
bin/hadoop dfs -mkdir / foodir |
| 删除名为/ foodir的目录 | bin/hadoop fs -rm -R / foodir |
| 查看名为/foodir/myfile.txt的文件的内容 | bin/hadoop dfs -cat /foodir/myfile.txt |
FS shell 针对的是那些与数据交互的脚本语言的应用。
DFSAdmin
DFSAdmin命令集用于管理HDFS集群。 这些是仅由HDFS管理员使用的命令。 以下是一些示例操作(命令对):
| 行动 | 命令 |
|---|---|
| 将群集置于Safemode |
bin/hdfs dfsadmin -safemode enter
|
| 生成DataNode的列表 | bin/hdfs dfsadmin -report |
| 重新投放或停用DataNode(s) | bin/hdfs dfsadmin -refreshNodes |
浏览器界面
一个典型的HDFS集群安装配置了一个Web服务器,通过一个可配置的TCP端口浏览HDFS命名空间。 这允许用户使用Web浏览器浏览HDFS命名空间并查看其文件的内容。
空间回收
文件删除和取消删除
如果启用垃圾箱配置, FS Shell删除的文件不会立即从HDFS中删除。 相反,HDFS将其移动到垃圾目录(每个用户在/user/<username>/.Trash下都有自己的垃圾目录)。 只要文件保留在垃圾箱中,文件就可以快速恢复。
最近删除的文件被移动到当前的垃圾目录( /user/<username>/.Trash/Current ),并且在可配置的时间间隔内,HDFS创建检查点(在 /user/<username>/.Trash/<date>下 )对于当前垃圾目录中的文件,并在过期时删除旧的检查点。
在垃圾桶中,文件的生命周期结束后,NameNode会从HDFS命名空间中删除该文件。 删除文件会导致与文件关联的块被释放。 请注意,用户删除文件的时间与HDFS中相应增加可用空间的时间之间可能存在明显的时间延迟。
以下是一个例子,它将显示FS Shell如何从HDFS删除文件。 我们在目录delete下创建了2个文件(test1&test2)
$ hadoop fs -mkdir -p delete/test1 $ hadoop fs -mkdir -p delete/test2 $ hadoop fs -ls delete/ Found 2 items drwxr-xr-x - hadoop hadoop 0 2015-05-08 12:39 delete/test1 drwxr-xr-x - hadoop hadoop 0 2015-05-08 12:40 delete/test2
我们将删除文件test1。 下面的注释显示该文件已被移至垃圾箱目录。
$ hadoop fs -rm -r delete/test1 Moved: hdfs://localhost:9820/user/hadoop/delete/test1 to trash at: hdfs://localhost:9820/user/hadoop/.Trash/Current
现在我们要用skipTrash选项删除这个文件,这个选项不会把文件发送到垃圾箱,它会从HDFS中完全删除。
$ hadoop fs -rm -r -skipTrash delete/test2 Deleted delete/test2
现在我们可以看到,垃圾目录只包含文件test1。
$ hadoop fs -ls .Trash/Current/user/hadoop/delete/ Found 1 items\ drwxr-xr-x - hadoop hadoop 0 2015-05-08 12:39 .Trash/Current/user/hadoop/delete/test1
所以文件test1进入垃圾桶,文件test2被永久删除。
降低复制因子
Hadoop JavaDoc API 。
文章评论