我们设计并实现了GFS:一个高扩展性,适用于数据密集型应用的分布式文件系统。运行在廉价的商用服务器上,它提供了容错能力,它能够在大量客户端请求时提供较好的整体性能。
当享用众多具有同样上述目的的分布式文件系统时,我们的设计驱动力来对应用的工作量和技术环境,无论是当前还是预期,也折射出与早期的文件系统的背离。这些引导我们重新检测传统选择或者探索一个不同的设计方式。
这种文件系统比较成功的满足了我们的存储需要,它作为一个数据的存储和处理平台被广泛的应用在google,作为研究和开发大数据集合数据。最大的分布式数据能够提供成千上万TB的数据存储,存储在无数个硬盘和机器上,同时可以支持大量的客户端并发调用。
简介:
我们已经设计和实现了GFS来满足在大数据处理方面快速增长的需要,GFS 和先前的文件系统,具
有相同的目标:扩展性,可用性,可靠性。
首先,组件故障是一个平常的事情而不是异常。GFS系统可能会有上千台机器组成,而且也会有相当级别的客户端(调用),组件的数量和质量实质上决定了某时的可用性和数据的恢复能力,我们遇到过很多问题,它们是有多方面原因造成的,例如应用的bug,操作系统的bug,人为的错误,硬盘问题,内存,网络,电力供应等等。所以,持续的监控,错误检测,容错,自动恢复这些特性将被融入整个系统。
再者,对于传统的标准而言,这些文件将是很庞大的,数GB的文件是很常见的。每个文件会包含许多像web文档这样的数据,当我们定期的去处理这些数TB的这种特性的数据. 快速增长的数据集合时,会发现管理它们将是一件很棘手的事情,尽管文件系统能够支持它。因此,设计假设和IO操作的参数/block尺寸等,需要重新对待。
第三,大部分文件数据的变更是通过append(追加)而不是重写的方式,在一个文件内随机写操作几乎是不存在的。一旦写入,那么这个文件只读,并且经常是有序读。有些能够构成大仓储,数据分析程序能够扫描。有些或许是应用程序持续产生的数据流。有些或许是档案数据,有些或许是供其他机器处理的中间数据(实时或者稍后)。针对这些特定的大文件存储方式,appending成为了性能优化和原子性保证的焦点,同时在客户端缓存数据的方式失去了优势。
第四,联合设计应用和文件系统api,通过增加我们的灵活性,使整个系统收益。例如,我们放松了GFS的数据一致性模型,大大简化了文件系统的设计,并且没有给应用系统增加额外的负担。我们引入了原子性append操作,可以让多个客户端操作并发的append一个文件,在它们之间却无需额外的同步。
多个GFS分布式环境应用与不同的目的,最大的一个超过1000个存储节点,超过300TB的硬盘存储,并且被无数个客户端大量的访问着。
设计总览:
在设计这个文件系统时,预期的设想使我们遇到了很多挑战。我们展示以下GFS设计的关键点。
1)系统构建在廉价的商业服务器上,且它们会经常出现故障。系统需要持续的自我监测,检测/容忍/并能在故障时及时修复。
2)系统存储适当量的大文件,我们预期有数百万的文件,文件在100M左右,当然GB级别的文件也是很常有的并且需要被高效的管理。小文件也必须支持,但是我们可能不会优化它们(意思是,针对大文件存储,是优化的重点)
3)主要包括2种方式的read:大数据流read和小随即读。在大数据流读中,个别的操作是读取上百KB,1MB或者更大的读取将是很常见的。同一客户端的连续操作经常会读取一个文件邻近的region。小随即读通常会在任意的offset读取几个KB的数据。对于性能敏感的应用经常批量和排序这些small reads,稳步向前操作文件,而不是来回移动。(顺序读取)
4)还会有很多大数据/顺序写操作,通过向文件append的方式进行。我们的文件经常作为producer-consumer(生产者-消费者)队列或者多路合并。多个生产者运行在一台机器上,将会并发的append文件。原子性与最小同步开销是必不可少的。
5)持续的高带宽比低延迟更加重要。我们的大部分目标应用,要求对大量数据的处理速度,而不是个别read或者write上严格的响应时间。
GFS提供了一些类似的文件系统接口,虽然它没有按照规范的API例如POSIX。文件通过目录层级组织起来,通过路径名称来识别。我们支持常用的操作如create/delete,open,close,read,write。
此外,GFS具有snapshot(快照)和记录追加(record append)操作。snapshot以较少的开支创建一个文件或者目录树(directory tree)的copy。Record append允许多个客户端并发的在同一个文件中追加数据,同时尚可确保每个client append操作的原子性,这对实现多路合并结果(multi-way merge)很有用,producer-consumer队列可以被多个客户端同时append而无需多余的lock。我们发现这些文件特性在构建大规模分布式应用时具有重要价值。
架构:
一个GFS分布式环境,有一个master和多个chunkserver构成,它可以被多个客户端访问。这些(server,client)通常是一些运行着用户级别的服务程序的商用linux机器。chunkserver和client运行在同一台机器也是很容易的,当然前提是机器的资源是允许使用的,同时较低的可用性是可以接受的。
文件被分成固定尺寸的chunks,每个chunk通过一个全局不变的64位chunk handle来标识,这个chunk handle是chunk创建时master机器分配的。chunkserver以linux文件的方式把chunks存储在本地磁盘上,对于read/write数据时将会操作由chunk handle和字节区间(byte range)指定的chunk。为了可用性,每个chunk被复制分散在多台机器上;默认情况下,每个chunk的replicas有3个,当然用户可以指定不同的file namespace中的region具有不同的replication的级别。
Master机器保存了文件系统的所有metadata(元数据),包括namespace(命名空间),访问权限控制,文件与chunks的影射关系,还有当前chunks的位置。它(master)也控制系统范围内的activities(活动),例如chunk lease(契约)管理,孤立(失效)chunk的回收,chunkserver间 chunk的迁移(migration)。master会间歇性的与每个chunkserver通讯,在heartbeat messages(心跳消息)中发送指令和收集chunkserver的状态。
GFS客户端程序(client code)会被引入到实现文件系统API的应用中,应用程序通过client code与master和chunkserver交互,来实现对数据的read和write。Client与master交互进行metadata方面的操作,但是实际数据的交互将直接与chunkserver通信。我们没有提供POSIX API,因此将不需要挂载到linux vnode层。
client和chunkserver均不会缓存文件数据。client缓存收益甚微,因为大部分应用stream through庞大的文件或者加工的数据的太大而无法缓存。没有缓存,意味着将无需考虑缓存数据同步的因素,这简化了客户端以及整个系统的设计。chunkservers也无需缓存文件数据,因为chunks存储在本地文件文件中,linux buffer cache已经把这些频繁访问的数据保存了在内存中。
单Master:
单Master很大程度上简化了我们的设计,使得master能够使用全局知识(global knowledge)来做复杂的chunk置放和复制方面的决策。此外,我们必须最小化对master的调用,所以master不会成为cluster的瓶颈。client从不通过master去read和write文件数据,相反,client会询问master 去连接哪个chunkserver,client会缓存这些信息,接下来操作就是client和chunkserver直接交互。
让我们解释一下一个简单的read操作的交互过程,参见图1.首先,使用固定chunk size,client将应用指定的文件名称和byte offset转换成文件系统的一个chunk索引(filename 和byte offset可以最终确定为某个file中的特定chunk信息)。然后,它(client)向master发送一个包含文件明和chunk索引的请求,master响应给client相应的chunk handle和replicas的位置。Client使用fileName和chunk index作为key来缓存这些信息。
此后client向其中一个replicas发送请求,多数情况下是最近的一个replicas。请求指定了chunk handle和此chunk中的byte range。后续对同一个chunk 的reads将无需与master交互,直到cache过期或者file被重新打开。事实上,client通常会在一次master交互中询问多个chunk的情况,避免了以后client-master的多次交互,事实上也不会带来额外的性能开支。
Chunk Size:
chunk size是一个关键的设计参数,我们选择了64MB,这个值通常比文件系统的block size要大很多。每个chunk replicas都是作为一个普通的linux文件存储在server上,并且会在需要的时候扩展它。延迟空间分配策略避免了对存储空间的浪费(内部碎片),也许最大的反对点就是这种大尺寸的chunk。
一个大尺寸的chunk你能够提供一些重要的优势。首先,它降低了client与master交互的次数,因为read和write同一个chunk只需要初始时与master一次交互获取chunk位置即可。它的降低,对于我们的workloads来说特别显著,因为应用大多数是顺序的read和write一个大文件。即使一些小的随即度操作(small random reads),客户端能够适当的缓存数TB数据中所有的chunk位置信息。再者,对于一个较大的chunk,客户端能够运行大量操作在此指定的chunk上,它能够通过保持现有的TCP连接(client-->chunkserver的连接)来降低网络开销。第三,它(大尺寸chunk设计)降低了master中metadata的存储尺寸,这就允许我们把metadata存储在内存中,也会带来其他的优势(接下来讨论)。
另一个方面开说,大尺寸chunk,即使采用延迟空间分配,也会有它的缺点。小文件包含少量的chunk,或许只有一个。在多个客户端访问同一个文件时,存储这些chunk的chunkserver可能成为热点(hot spots)。实践中,hot spots还不是一个主要的问题,因为我们的应用大多数情况下是顺序read一个多chunks的大文件。
可是,在hotspots尚未发展时,GFS开始使用的是批量队列系统:一个可执行文件作为一个single-chunk的文件被写入到GFS,然后同时在多个机器上启动。存储这个可执行文件(executeable)的几个chunkservers在数个请求同时访问时可能会过载。我们解决了这个问题,通过使用更高的复制因子(higher replication factor)存储这个执行文件,使被处理队列系统错开应用启动的时间。在这种情况下,一个潜在的解决办法就是允许客户端可以从其他客户端读取数据。(事实上此解决办法是不可取的)
Metadata:
master存储3个主要类型的metadata:file and chunk namespaces(文件和chunk的命名空间),the mapping from files to chunks(文件与chunk影射关系),the location of each chunks‘ replicas(chunk replicas位置)。这些元数据保存在master的内存中。前2种类型的metadata(namespaces ,file-chunk mapping)也会通过记录变更的方式持久存储一个操作日志文件中(operation log),这个操作日志文件存储在master的本地磁盘并且被replicated在其他的远程机器上(和chunk的机制一样)。有了日志,我们就能够简单而且可靠的去更新master的状态,无需担心master机器crash所带来的不一致问题。
因为metadata存储在内存中,master操作将是很迅速的。此外,对与master后台间歇性扫描整个state也将是很简单和高效的。间歇性扫描,是用来实现chunk回收/重复制故障机器的chunk/chunk迁移(负载均衡,和跨chunkserver磁盘空间使用率)。
这种内存存储方式,有一个潜在的顾虑是chunk的数量,因为整个系统的容量会受到master内存大小的限制。在实践中,这似乎不是一个很严重的限制。每个64MB的chunk,在master中之需要64B的metadata存储,大部分chunk都是满的(full)因为通常一个文件会包含多个chunks,只有最后一个(chunk)是可以被filled(填充数据)。类似,file namespace数据通常只需要少于64B的数据,因为它(master)存储file names会进行前缀压缩。
如果需要支撑更大的文件系统,那么给master机器增加内存也是很简单和廉价的。因此将metadata内存储存,可以获得灵活性/性能/可用性/简易性等。
Chunk位置:
master不会持久存储chunkserver所持有的replicas信息,它(master)仅仅是在启动后去各个chuankserver上poll这些数据,然后会保持自己所持有chunk信息的更新,因为它控制了所有chunk位置分配,以及使用定期的heartbeat消息监控chunkserver的状态。
我们起初尝试过在master上持久存储chunk位置信息,但是我们觉得master启动时从chunkserver请求这些数据然后间歇性同步的设计更加简单。这样可以避免一些问题:保持master和chunkservers的同步(chunkserver的加入,离群),修改名称失败,重启等等。在一个具有数百台机器的分布式环境中,这些情况还是会经常发生的。
可以从另一个方向来认识这种设计,chunkserver上是否持有chunk,chunkserver具有最终决定权。那就没有必要在master中再持久存储一份视图数据,而且chunkserver的一些error会导致chunk信息的丢失(硬盘损坏或者不可用),甚至有的操作会重命名chunkserver。
GFS论文整理(二):[http://shift-alt-ctrl.iteye.com/blog/1842286]
GFS论文整理(三):[http://shift-alt-ctrl.iteye.com/blog/1842509]
GFS论文整理(四):[http://shift-alt-ctrl.iteye.com/blog/1842510]
相关推荐
《Google File System》(简称GFS)是一篇由Google发布的关于其内部文件系统架构的技术论文,该论文揭示了Google如何解决大规模数据存储的问题。GFS是为了解决海量数据处理而设计的一种分布式文件系统。它提供了一个...
这37篇论文系刘鹏教授的研究生龚传消化整理,欢迎下载! 1、 Atmosphere-Ocean Climate (性能测试) 这篇文章讨论了高性能标准测试应用程序在亚马逊EC2云计算系统中的性能。经过测试发现EC2云计算系统是一个可靠的...
谷歌文件系统(GFS)设计的目标是支持大规模并行计算,提供高吞吐量和容错性。主要知识点包括: - 分布式文件系统的基本架构,包括主服务器、Chunk服务器和客户端。 - 大块(Chunk)存储,每个文件被分割成固定...
Hadoop的发展历程可以追溯到2003年,Google发表的GFS论文。随后,Doug Cutting在2005年基于这两篇论文开发出了Hadoop的早期版本。Hadoop逐渐发展成为一个成熟的开源项目,并在2008年成为Apache开源社区的顶级项目。...
在这个文档集中,"大数据论文24(1).docx" 很可能是刘佳敏撰写或整理的一篇关于大数据的学术论文,可能涵盖了大数据的应用、挑战、技术发展以及相关的解决方案。 Hadoop 是一个开源的分布式计算框架,主要用于处理和...
1. 大数据技术的基础由谷歌首先提出,这主要体现在谷歌的三篇著名论文——MapReduce、GFS(Google File System)和Bigtable,它们为大数据处理提供了分布式计算框架和大规模数据存储解决方案。 2. 大数据的起源是...
- HDFS是Hadoop分布式文件系统,基于Google发布的GFS论文设计开发。它在通用硬件上运行,具有高容错性、高吞吐量和大文件存储能力。HDFS的三个主要组件包括NameNode、DataNode和Client。 - NameNode负责存储和生成...
1. **Hadoop 发展历史**:Hadoop 的起源可以追溯到 Google 的 MapReduce 和 GFS 论文,它由 Doug Cutting 创建并以他的儿子的玩具大象命名。随着时间的推移,Hadoop 成为了大数据处理的标准工具,经历了多个版本的...
1. **Hadoop概述**:Hadoop是基于Google的GFS(Google File System)和MapReduce论文设计的,旨在提供分布式存储和并行计算能力。它遵循“分而治之”的原则,通过将大数据拆分为小块并在多台服务器上并行处理,极大...
1. **大数据技术起源**:大数据技术的基础由谷歌提出,主要体现在其发表的三篇论文,即GFS(Google File System)、MapReduce和Bigtable,它们分别解决了大规模数据的存储、计算和索引问题。 2. **大数据的起源领域...