谷歌的大数据论文 The Google File System,是当前分布式存储的开山之作。很多分布式存储系统均依据或借鉴其思想进行实现,其中就包括大名鼎鼎的Hadoop系统。
本文旨在通过对论文《The Google File System》的梳理,了解其系统设计和实现的核心思想,加深自己对Hadoop等分布式存储系统的理解。
设计目标
实现一个面向大规模数据密集型应用的、可伸缩的分布式文件系统。
系统特点
- 运行在廉价的普遍硬件设备上
- 提供灾难冗余的能力
- 为大量客户机提供了高性能的服务
系统规模
- 最大的一个集群利用数千台机器的数千个硬盘
- 提供了数百(300) TB 的存储空间
- 同时为数百个客户机服务
设计思想
- 组件失效被认为是常态事件,而不是意外事件。GFS 包括几百甚至几千台普通的廉价设备组装的存储机器,同时被相当数量的客户机访问。 GFS 组件的数量和质量导致在事实上,任何给定时间内都有可能发生某些组件无法工作,某些组件无法从它们目前的失效状态中恢复。所以,持续的监控、错误侦测、灾难冗余以及自动恢复的机制必须集成在 GFS 中。
- 以通常的标准衡量,我们的文件非常巨大。经常需要处理快速增长的、并且由数亿个对象构成的、数以 TB 的数据集。采用管理数亿个 KB 大小的小文件的方式是非常不明智的,尽管有些文件系统支持这样的管理方式。因此,设计的假设条件和参数,比如 I/O 操作和 Block 的尺寸都需要重新考虑。
- 绝大部分文件的修改是采用在文件尾部追加数据,而不是覆盖原有数据的方式。有些文件一旦写完之后,对文件的操作就只有读,而且通常是按顺序读。大量的数据符合这些特性,比如:数据分析程序扫描的超大的数据集;正在运行的应用程序生成的连续的数据流;存档的数据。对于这种针对海量文件的访问模式,客户端对数据块缓存是没有意义的,数据的追加操作是性能优化和原子性保证的主要考量因素。
- 应用程序和文件系统 API 的协同设计提高了整个系统的灵活性。比如,我们放松了对 GFS 一致性模型的要求,这样就减轻了文件系统对应用程序的苛刻要求,大大简化了 GFS 的设计。我们引入了原子性的记录追加操作,从而保证多个客户端能够同时进行追加操作,不需要额外的同步操作来保证数据的一致性。
系统架构
一个 GFS 集群包含一个单独的 Master 节点、多台 Chunk 服务器,并且同时被多个客户端访问。
- GFS 存储的文件都被分割成固定大小的 Chunk,分别存储在多台服务器上(默认3台)。
在 Chunk 创建的时候, Master 服务器会给每个 Chunk 分配一个不变的、全球唯一的 64 位的 Chunk 标识。 Chunk 服务器把 Chunk 以 Linux 文件的形式保存在本地硬盘上,并且根据指定的 Chunk 标识和字节范围来读写块数据。出于可靠性的考虑,每个块都会复制到多个块服务器上。缺省情况下,我们使用 3 个存储复制节点,不过用户可以为不同的文件命名空间设定不同的复制级别。
- Master 节点管理所有的文件系统元数据。
这些元数据包括名字空间、访问控制信息、文件和 Chunk 的映射信息、以及当前 Chunk 的位置信息。 Master 节点还管理着系统范围内的活动,比如, Chunk 租用管理、孤儿 Chunk的回收、以及Chunk 在 Chunk 服务器之间的迁移。 Master 节点使用心跳信息周期地和每个 Chunk服务器通讯,发送指令到各个 Chunk 服务器并接收 Chunk 服务器的状态信息。
GFS 客户端代码以库的形式被链接到客户程序里。客户端代码实现了 GFS 文件系统的 API 接口函数、应用程序与 Master 节点和 Chunk 服务器通讯、以及对数据进行读写操作。客户端和 Master 节点的通信只获取元数据,所有的数据操作都是由客户端直接和 Chunk 服务器进行交互的。
简单读取的流程:
- 客户端把文件名和程序指定的字节偏移,根据固定的 Chunk 大小,转换成文件的 Chunk 索引
- 它把文件名和 Chunk 索引发送给 Master 节点
- Master 节点将相应的 Chunk 标识和副本的位置信息发还给客户端
- 客户端用文件名和 Chunk 索引作为 key 缓存这些信息
- 客户端发送请求到其中的一个副本处,一般会选择最近的。请求信息包含了 Chunk 的标识和字节范围。
在对这个 Chunk 的后续读取操作中,客户端不必再和 Master 节点通讯了,除非缓存的元数据信息过期或者文件被重新打开。实际上,客户端通常会在一次请求中查询多个 Chunk 信息, Master 节点的回应也可能包含了紧跟着这些被请求的 Chunk 后面的 Chunk 的信息。在实际应用中,这些额外的信息在没有任何代价的情况下,避免了客户端和 Master 节点未来可能会发生的几次通讯。