GFS与HDFS解析
谷歌在2002年发表了一篇论文,首次公开「谷歌文件系统」(Google File System,简称GFS)。HDFS是GFS的一个开源实现,由雅虎开发并开源,属于Hadoop项目的一部分。
设计
任何一个系统的架构设计,脱离了使用场景与假设,都是耍流氓。
以下是HDFS的假设与设计目标。
特性 | 假设 | 目标 |
---|---|---|
容忍硬件故障 | 硬件错误是常态而非异常 | 分布式文件系统由上千台服务器组成,任一组件都有可能失效。因此架构设计的目标是错误检测和快速自动恢复。 |
流式数据访问 | 大数据应用需要流式访问数据集,即多批处理,少交互式处理 | 数据访问的高呑吐量优先于低延迟。(因此为了提高呑吐量,修改了POSIX的部分语义。) |
大数据集 | 应用有很大的数据集(TB级别) | 支持大文件存储,高数据传输带宽,线性拓展到上百个节点。 |
简单一致性模型 | 「一次写入多次读取」的文件访问模型。文件写后不改 | 这个假设简化了数据一致性问题,使高呑吐量的数据访问成为可能。映射归并类应用适用这种模型。 |
移动「计算」比「数据」更划算 | 计算本地性,即计算离它操作的数据越近就越高效 | 为应用提供将「计算代码」移动到数据附近的接口(注:计算下沉) |
可移植 | 应用可能运行在异构的设备上 | 系统可移植到不同设备上 |
个人认为GFS最大的创新是改变了业界的惯性思维,将计算下沉到数据节点。因为之前学术界普遍认为「带宽是无限的」。传统的网络系统移动数据。
架构
采用主从架构。一个集群由一个主节点和多个从节点构成。主节点也称为「名字节点」(namenode),从节点也称为「数据节点」(datanode)。
名字节点
它负责
- 管理文件系统的命名空间(或称为文件树)以及客户端对文件的访问。
- 执行文件树的操作,包括创建,移动文件或目录。
持久化
所有文件树的修改记录,都会记录在名为EditLog的事务日志中。例如,创建文件或修改文件的副本数。EditLog(改志)保存在主节点的本地文件系统中。
文件树(命名空间)的状态,称之为FsImage,包括文件的属性和文件到数据块的映射(BlockMap),也存储在主节点的本地文件系统。
FsImage可以认为是EditLog的快照,且加载在内存上。命名节点在启动时和周期性地将「改志」应用在快照上,生成新的快照和删除旧的「改志」。
高可用
虽然是单主节点,为了保证可用性,实际上有个镜像主节点。如果活跃主节点挂了,镜像节点会代替之。
数据节点
它负责存储数据块,以及数据的读写操作。HDFS默认数据块大小是64MB。
一份文件实际上会存储多份副本。
可以理解为两层抽象,即文件层和数据块层。名字节点管理文件,数据节点管理数据块。一个文件由一个或多个数据块组成。
读
读文件流程如下:
- 客户端请求读。
- 从命名节点获得文件的块及位置信息。
- 客户端直接与数据节点交互读数据。
- 关闭连接。
写
写的过程比较复杂。GFS是允许附加(append)写操作的,而HDFS不允许,因此GFS的写操作要复杂得多。
GFS使用租约(lease)来保证一致性的修改顺序。主节点授予一个数据块的租约给一个数据节点。这个数据节点被称为这个数据块的「主」。「主」对所有针对这个数据块的修改选定一个顺序。其它从点修改时都遵循这个顺序。由此得到全局修改顺序。
具体的写流程请参考GFS论文。
删
删除文件比较简单,HDFS会将文件移动到/trash目录,等待下次清理时才会被真正删除。