我们设计并实现了Google文件系统(Google File System - GFS),用来满足Google迅速增长的数据处理需求。GFS与过去的分布文件系统拥有许多相同的目标,例如性能,可伸缩性,可靠性以及可用性。然而,它的设计还受到我们对我们的应用负载和技术环境观察的影响,不管现在还是将来,我们和早期文件系统的假设都有明显的不同。所以我们重新审视了传统的选择,采取了完全不同的设计观点。
首先,组件失效不再被认为是意外,而是被看做正常的现象。这个文件系统包括几百甚至几千台普通廉价部件构成的存储机器,又被相应数量的客户机访问。组件的数量和质量几乎保证,在任何给定时间,某些组件无法工作,而某些组件无法从他们的目前的失效状态恢复。我们发现过,应用程序bug造成的问题,操作系统bug造成的问题,人为原因造成的问题,甚至硬盘、内存、连接器、网络以及电源失效造成的问题。所以,常量监视器,错误侦测,容错以及自动恢复系统必须集成在系统中。
其次,按照传统的标准来看,我们的文件非常巨大。数G的文件非常寻常。每个文件通常包含许多应用程序对象,比如web文档。传统情况下快速增长的数据集在容量达到数T,对象数达到数亿的时候,即使文件系统支持,处理数据集的方式也就是笨拙地管理数亿KB尺寸的小文件。所以,设计预期和参数,例如I/O操作和块尺寸都要重新考虑。
第三,在Google大部分文件的修改,不是覆盖原有数据,而是在文件尾追加新数据。对文件的随机写是几乎不存在的。一般写入后,文件就只会被读,而且通常是按顺序读。很多种数据都有这些特性。有些数据构成数据仓库供数据分析程序扫描。有些数据是运行的程序连续生成的数据流。有些是存档的数据。有些数据是在一台机器生成,在另外一台机器处理的中间数据。对于这类巨大文件的访问模式,客户端对数据块缓存失去了意义,追加操作成为性能优化和原子性保证的焦点。
第四,应用程序和文件系统API的协同设计提高了整个系统的灵活性。例如,我们放松了对GFS一致性模型的要求,这样不用加重应用程序的负担,就大大的简化了文件系统的设计。我们还引入了原子性的追加操作,这样多个客户端同时进行追加的时候,就不需要额外的同步操作了。论文后面还会对这些问题的细节进行讨论。
为了不同的应用,Google已经部署了许多GFS集群。最大的一个,拥有超过1000个存储节点,超过300T的硬盘空间,被不同机器上的数百个客户端连续不断的频繁访问着。