官方HDFS架构设计原理说明(下)

玩了HDFS已经有好多年了,之前一直都是边学边用,直到现在才真正有时间记录一下学到的知识O(∩_∩)O

6. 文件系统元数据的持久化


HDFS的命名空间是由命名节点NameNode来存储的。NameNode使用了一个叫EditLog的事务日志来持续记录文件系统元数据的每一次更改,例如在HDFS创建一个新的文件,NameNode会在EditLog里面插入一条这样的记录。类似地,修改文件的复制因子也会在EditLog里面插入一条记录。NameNode使用本地服务器操作文件系统中的文件来存储EditLog。整个文件系统的命名空间,包括数据块的映射和文件系统的属性配置,都保存在一个叫FsImage的文件里,这个FsImage文件也是保存在NameNode的本地文件系统里。

NameNode将整个文件系统的命名空间和文件Blockmap的镜像保存在内存中。关键的元数据被设计成紧凑存储的,这使得一个有4GB内存的NameNode足以支持处理大量的文件和目录。当NameNode启动时,它从磁盘读取FsImage和EditLog文件,将EditLog的所有事务应用于FsImage的内存中,然后将这个新版本的FsImage刷新到磁盘中。因为事务已经被持久化到FsImage中,所以可以截去旧的EditLog,这个过程叫做检查点checkpoint。在当前实现中,checkpoint仅在NameNode启动时发生,而周期性的checkpoint功能正在实现中。

DataNode将HDFS的数据以文件形式存储到本地的文件系统中,而它在存储文件的时候又会将数据分成多个数据块分别存储在不同的文件中。DataNode不会将所有的数据块文件都存放到同一个目录中,而是它使用启发式方法来确定每个目录的最佳文件数,并适当地创建子目录。在本地同一个目录下创建所有的数据块文件不是最优的,因为本地文件系统可能无法在单个目录中有效地支持大量文件。当DataNode启动的时候,它将扫描它的本地文件系统,生成与这些本地文件相对应的所有数据块的列表,并将此列表发给NameNode,这个列表被称为Blockreport。

7. 通信协议

所有HDFS的通信协议都是构建在TCP/IP协议之上。一个客户端和NameNode的一个可配置的TCP端口建立连接使用的是客户端协议Client Protocol,DataNodes和NameNode通讯使用的是数据节点协议DataNode Protocol,远程程序调用(RPC)抽象封装了Client Protocol和DataNode Protocol。按照设计,NameNode从不发起任何RPC。相反,它只会响应DataNodes或客户端发出的RPC请求。

8. 稳健性

HDFS设计的主要目标是即使出现故障的情况下也能够可靠地存储数据。三种常见的故障类型是NameNode故障,DataNode故障和网络分裂。

8.1 数据磁盘故障,心跳和重新复制数据

每一个DataNode会周期性地向NameNode发送一个心跳包。网络分裂出现时可能会造成部分DataNodes和NameNode断开连接,NameNode会根据丢失心跳包检测到此类情况。NameNode会标记那些丢失心跳包的DataNodes为dead状态,并且不会再向其转发任何新的IO请求,而它们存储的数据将不再可用。DataNode被标记为dead可能会导致某些数据块的复制因子低于其指定值。NameNode会不断地跟踪哪些数据块需要复制,并在必要时启动数据复制。重新复制数据的必要性有很多,例如:DataNode故障,副本损坏,DataNode所在的磁盘损坏,或者文件的复制因子增加。

为了避免由于DataNodes状态摆动引起的数据频繁复制,标记DataNodes为dead状态的超时时间默认被设为保守的10分钟以上,计算公式为:

2 * dfs.namenode.heartbeat.recheck-interval + 10 * dfs.heartbeat.interval = 2 * 300000(ms) + 10 * 3(s) = 10.5 minutes

8.2 集群数据重新均衡

HDFS的架构是与数据重新均衡方案兼容的。例如,如果一个DataNode的可用空间低于某个阀值,数据会自动从一个DataNode移动到另外一个DataNode;如果对某些文件的访问量突然剧增,数据会被额外地复制和集群的其它数据会被重新均衡。这些类型的数据重新均衡方案尚未实现。

8.3 数据完整性

从DataNode读取的数据块有可能会损坏,这可以是由于存储设备故障、网络故障、或者有bugs的代码而导致的。HDFS的客户端软件实现了checksum方法对文件内容进行校验,当客户端创建一个HDFS文件时,它会计算文件的每个数据块的校验和,并将这些校验和存储在同一命名空间中的独立隐藏文件中。当客户端读取文件时,它会验证从DataNode读取的数据与对应的校验和文件是否匹配。如果不匹配,则客户端会选择从另外一个有该数据副本的DataNode读取数据。

8.4 元数据磁盘故障

FsImage和EditLog是HDFS的核心数据结构,这些文件的损坏可以导致HDFS不能正常工作。因此,NameNode可以配置支持维护多个FsImage和EditLog的副本。对FsImage或EditLog的任何更新都会触发FsImage和EditLog副本的同步更新。多个FsImage和EditLog的副本同步更新会降低NameNode可以支持处理的每秒事务效率。然而,这些影响是可以接受的,因为尽管HDFS应用是数据密集型的,但它们不是元数据密集型的。当NameNode重新启动时,它会选择最近一致的FsImage和Editlog文件来使用。

以防元数据故障的另一个选择是配置多个NameNodes,使用NFS的共享存储或分布式EditLog(称为Journal)来启动高可用,后者是推荐的方法。

8.5 快照

快照支持保存在特定时刻的数据,此功能的一个用法是将损坏的HDFS实例回滚到之前的一个好的时间点。

9. 数据组织

9.1 数据块


HDFS是设计来存储非常大的文件,与HDFS兼容的应用程序是用来处理那些大文件的。这些应用程序通常只写入一次数据,但读取多次,而且需要满足一定的读效率。HDFS支持写一次读多次的语义,它默认的数据块大小是128MB。因此,一个HDFS的文件会分割为128MB的数据块,如果可能,每个数据块会保存在不同的DataNode。

9.2 数据写入过程

一个客户端创建一个文件的请求是不会立即发送到NameNode的,事实上在开始时,HDFS客户端会先把数据缓存到本地的一个缓冲区。应用程序会把数据库重定向写入到此缓冲区,当缓冲区累积的数据超过配置的一个数据块大小时,客户端才会连接NameNode。NameNode将文件名插入到文件系统层次结构中并为其分配存储空间,接着向客户端返回DataNode的标识和数据块的路径。然后客户端将数据块从本地缓冲区传输到指定的DataNode。当关闭一个文件时,本地缓冲区剩余的未传输的数据会传输到DataNode中,客户端然后会告诉NameNode文件已经关闭。此时,NameNode会将文件创建操作提交到持久化存储。如果NameNode在文件关闭之前宕机,文件将会丢失。

上述方法是在仔细考虑了在HDFS上运行的目标应用程序后才采用的。这些应用程序需要流式写入文件,如果客户端没有使用任何客户端缓冲直接写入远程文件,那么网络速度和网络拥塞将会极大地影响吞吐量。这种方法并非没有先例,早期的分布式文件系统,例如AFS使用了客户端缓存来提高性能。为了实现更高的数据写入性能,POSIX的需求已经被放宽。

9.3 数据复制管道

正如上一节所述,当客户端写入数据到HDFS文件的时候,数据是先写入到本地的一个缓冲区。假设配置的复制因子是3,当本地缓冲区累积到一个数据块的大小时,客户端连接NameNode获得一个DataNodes的列表,该列表包含将会保存那个数据块副本的DataNodes。客户端然后将那个数据块传输到第一个DataNode,第一个DataNode以小部分接收数据,将每小部分数据写入到本地存储,并传输到列表的第二个DataNode。第二个DataNode依次接收和写入每小部分的数据到本地存储,并传输到列表的第三个DataNode。最后,第三个DataNode将每小部分数据写入到本地存储。因此,一个DataNode可以接收来自之前DataNode的数据,并同时把数据转发到下一个DataNode。因此,数据复制是从一个DataNode传输给下一个DataNode。

10. 数据访问

应用程序可以有很多方法访问HDFS,HDFS自带提供了一个FileSystem的Java API供应用程序使用,用C语言封装此Java API的接口和REST API也可用。另外,HTTP浏览器也可以用来浏览HDFS实例的文件。通过使用NFS网关,HDFS可以被加载到客户端的本地文件系统。

10.1 FS Shell


HDFS允许以文件和目录的形式组织管理用户数据,它提供了一个称为FS shell的命令行接口让用户与HDFS中的数据进行交互。该命令集的语法类似于用户已经熟悉的其它shell(例如bach、csh)。下面是一些例子:
  • 在根目录/下面创建一个foodir的子目录:  bin/hadoop fs -mkdir /foodir
  • 删除根目录/下面的foodir子目录:            bin/hadoop fs -rm -R /foodir
  • 查看文件/foodir/myfile.txt的内容:             bin/hadoop fs -cat /foodir/myfile.txt
FS shell是针对需要使用脚本语言与存储数据进行交互的应用程序设计的。

10.2 DFSAdmin

DFSAdmin命令集是用于管理HDFS集群,这些命令是仅供HDFS管理员使用。下面是一些例子:
  • 使集群进入安全模式:  bin/hdfs dfsadmin -safemode enter
  • 生成DataNodes列表: bin/hdfs dfsadmin -report
  • 刷新DataNode(s):   bin/hdfs dfsadmin -refreshNodes
10.3 浏览器接口

典型的HDFS安装配置了Web服务器用于通过可配置的TCP端口访问HDFS的namespace,这允许用户通过Web浏览器访问HDFS的namespace和查看其文件的内容。

11. 空间回收

11.1 文件删除和恢复


如果回收站被启用,通过FS Shell删除的文件不会被立即删除,而是先移到一个垃圾目录(每个用户在/user/<username>/.Trash下都有自己的垃圾文件目录),只要文件还保留在回收站就可以被快速的恢复。

最近被删除的文件会被移到/user/<username>/.Trash/Current目录,在配置的间隔内,HDFS会在/user/<username>/.Trash/<date>创建文件的checkpoints目录,把Current目录下面的文件都移到该checkpoints目录里面,并删除过期的checkpoints目录。详细请参考FS shell的expunge命令。

在回收站的文件过期后,NameNode会从HDFS的namespace删除该文件,关联的数据块空间会被释放。注意,在用户执行删除文件后和HDFS真正释放空间会有一点延时。

下面是如何使用FS Shell删除文件的一个例子:
  • 在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,执行后会提示test1移动到用户的.Trash/Current目录
$ hadoop fs -rm -r delete/test1
Moved: hdfs://localhost:8020/user/hadoop/delete/test1 to trash at: hdfs://localhost:8020/user/hadoop/.Trash/Current
  • 使用skipTrash参数直接删除test2
$ hadoop fs -rm -r -skipTrash delete/test2
Deleted delete/test2
  • 查看回收站,只有test1,而没有test2
$ 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

11.2 减小复制因子

当减小文件复制因子时,NameNode会选择可以删除的多余副本。在下一个Heartbeat把此信息传输给DataNode,此DataNode然后删除相应的数据块并释放空间。需要再次注意的是,调用setReplication API后和释放空间会有一点延时。

* 参考HDFS架构(2.7.3版本)官方链接:http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html

END O(∩_∩)O
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值