The Hadoop Distributed File System 论文阅读
#0. 摘要
HDFS 的设计目标是可靠存储大数据集,并提供高吞吐量的数据访问。
#1. 引言和相关工作
Hadoop 提供了分布式的文件系统和使用 MapReduce 范式来分析和处理大数据集的框架。
和其他系统类似,HDFS 把元数据保存在单独的服务器上,称为 NameNode。应用数据保存在其他服务器上,称为 DataNode。
HDFS 的 DataNode 不使用类似 RAID 的数据保护机制。而是采用多副本的方式来保证数据的可靠性。
某些分布式存储系统设计了分布式的系统来管理 namespace。 Ceph 使用动态子树分区算法来管理元数据。 GFS 使用多个 Master 来管理元数据。 Lustre 2.2 使用了聚类 namespace。
#2. 架构
#A. NameNode
HDFS 的名字空间是文件和目录的树形结构。文件和目录在 NameNode 中表示成 inode,inode 包含文件的属性,例如权限、修改和访问时间、namespace 和磁盘配额。文件内容被分割成 128MB 大小的块,每个块被独立备份保存到 3 个 DataNode 上。 NameNode 维护着 namespace 树和块到 DataNode 的映射。 HDFS 客户端首先向 NameNode 请求文件的块位置,然后和最近的 DataNode 通信读取块数据。当写数据的时候,客户端首先请求 NameNode 分配三个块,然后以 pipeline 的方式将数据写入到 DataNode 上。
HDFS 把整个 namespace 保存在内存中。 namespace 的元数据包含 inode 数据和每个文件对应的块列表,称为 image。 image 保存在本地文件系统上,称为 checkpoint。 NameNode 还额外保存 image 的变更日志,称为 journal。
#B. DataNodes
DN 使用两个本地文件保存一个块的数据:一个文件保存块数据,另一个文件保存块的元数据,包括 checksum 和 generation stamp。
DN 启动的时候,会先和 NN 连接然后进行一次 handshake,NN 会验证 DN 的 namespace ID 和软件版本是否匹配,如果任意一个不匹配,DN 就会退出。
namespace ID 会在格式化文件系统的时候生成,永久保存在集群的所有节点上。 ID 不同的节点不能加入到这个集群中,保证了集群的一致性。新初始化的 DN 没有 namespace ID,可以加入任何集群。
handshake 之后,DN 会向 NN 注册自己。NN 会给 DN 分配一个 storage ID,这个 ID 是 DN 的内部 ID,保证即使 DN 的 IP 地址或者端口改变, NN 也能识别出这个 DN。
DN 会定期给 NN 发送 block report 报告自己拥有的 block 副本。 block report 中包含 block id,generation stamp 还有每个 block 的长度。第一次注册的时候,会立即发送一次,随后每小时发送一次。
正常操作期间,DN 给 NN 发送 heartbeat,确认自己还活着。默认每 3 秒发送一次。如果 NN 在 10 分钟内没有收到 DN 的 heartbeat,就会认为这个 DN 挂了,随后开始安排数据复制过程。
DN 的 heartbeat 也包含了一些统计信息,例如总的容量、剩余容量、正在传输的数据量等。用于 NN 做一些决策时参考。
NN 不会直接向 DN 发送命令,而是通过对 heartbeat 的响应来发送命令。命令包括:
- 复制 block 到另一个节点;
- 删除本地的 block;
- 重新注册或者退出;
- 立即发送 block report。
NN 每秒能处理数千的 heartbeat,不会影响其他的 NN 操作。
#C. HDFS 客户端
应用程序通过 HDFS 客户端库访问 HDFS。
HDFS 客户端支持读取、写入、删除文件,创建和删除目录。
读文件时,HDFS 客户端先询问 NN 获取文件的块所在的 DN 的列表。然后联系 DN 请求所需的 block。写文件时,HDFS 客户端先询问 NN 选择三个 DN 保存第一个 block,然后客户端负责组织一个 pipeline 然后开始写入。当第一个 block 写完后,客户端继续询问 NN 请求下一个 block 的 DN。
HDFS 提供了一个 API 暴露 block 位置给应用程序,允许 MapReduce 框架把任务调度到数据所在的节点上,减少网络传输。
HDFS 也允许应用程序设置文件的副本数,如果一个文件需要高频率访问,可以增加副本数。
#D. Image 和 Journal
文件系统目录结构的元数据称为 image。对 image 的每一次持久化记录是一个 checkpoint。 journal 是文件系统目录结构的 WAL。对于每一次客户端事务,NN 会先把操作写入 journal 中,flush 和 sync 之后,才会返回给客户端。 checkpoint 文件创建后不会修改,只会被新的替换。在启动的时候,NN 会读取最新的 checkpoint 和 journal,然后恢复到最新的状态。恢复后,新的 checkpoint 和空的 journal 会被创建。
如果 checkpoint 或者 journal 损坏,整个文件系统会被不可用,因此这两个文件可以配置为保存多个副本。推荐的配置是放置在不同的 volume 上,还有一个放在远程的 NFS 上。
NN 是一个多线程系统,可以同时处理多个客户端的请求。 flush 和 sync 操作就变成了一个瓶颈,因为它们是同步的。 NN 会把不同客户端发起的操作合并成一个 batch,只要有一个线程完成了 flush 和 sync,其他线程就可以继续处理下一个请求。
#E. CheckpointNode
NN 节点除了服务客户端请求外,还可以执行其他两种任务之一:CheckpointNode 和 BackupNode。执行哪一个任务在节点启动时执行。
CheckpointNode 通常运行在和 NN 不同的节点上,因为它和 NN 一样需要大量的内存。它会从 NN 下载当前的 checkpoint 和 journal,然后进行 compaction,将合并后的 checkpoint 返回给 NN。
创建新的 checkpoint 会导致 NN 截断 journal。
#F. BackupNode
BackupNode 会和 NN 保持同步。