The Google File System

谷歌文件系统是一个可扩展的分布式文件系统,专为大规模数据密集型应用程序设计,能在廉价硬件上提供容错功能。文件系统针对大规模文件(通常GB级)、追加写入和顺序读取优化,允许并发追加操作。主服务器负责元数据管理,通过块复制确保容错,而客户端直接与块服务器进行数据传输。系统通过快照和记录追加功能增强,适用于分布式应用程序。
摘要由CSDN通过智能技术生成

The Google File System

ABSTRACT

我们设计并实现了谷歌文件系统,这是一个可扩展的分布式文件系统,适用于大型分布式数据密集型应用程序。它在廉价的商用硬件上运行时提供容错功能,并为大量的客户端提供较高的聚合性能

虽然与以前的分布式文件系统有许多相同的目标,但我们的设计是由对应用程序工作负载和技术环境(当前和预期的)的观察驱动的,这些观察反映了与以前一些文件系统假设的明显背离。这促使我们重新审视传统的选择,探索完全不同的设计点。

     文件系统已经成功满足了我们的存储需求。它被广泛部署在谷歌作为存储平台,用于我们服务中使用的数据的生成和处理,以及需要大型数据集的研发工作。迄今为止最大的集群在超过1000台机器上的数千个磁盘上提供了数百tb的存储,并且由数百个客户机并发访问。

    在本文中,我们介绍了旨在支持分布式应用程序的文件系统接口扩展,讨论了我们设计的许多方面,并报告了从微基准测试和真实世界使用两方面的测量结果。

1. INTRODUCTION

1.1 设计动机  

    它的设计是由对应用程序工作负载和技术环境(包括当前的和预期的)的关键观察驱动的,这些观察反映了与一些早期文件系统设计假设的明显背离。

     1. 首先,组件故障是正常现象,而不是异常现象。该文件系统由数百甚至数千台存储机器组成,这些存储机器由廉价的商品部件构建,并由相当数量的客户端机器访问。这些组件的数量和质量实际上保证了一些组件在任何时候都无法正常工作,而一些组件则无法从当前的故障中恢复过来。我们已经看到了由应用程序错误、操作系统错误、人为错误以及磁盘、内存、连接器、网络和电源故障引起的问题。因此,持续监控、错误检测、容错和自动恢复必须是系统不可或缺的部分。

    2. 其次,按照传统标准,文件是巨大的。多gb文件很常见。每个文件通常包含许多应用程序对象,如web文档。当我们经常使用由数十亿个对象组成的许多tb组成的快速增长的数据集时,即使在文件系统能够支持的情况下,管理数十亿个大约kb大小的文件也是非常笨拙的。因此,设计假设和参数,如I/O操作和块大小必须重新考虑

      3 .第三,大多数文件都是通过添加新数据而不是覆盖现有数据来改变的。文件中的随机写入实际上是不存在的。一旦写入,文件就只能被读取,而且通常只能按顺序读取。各种数据都具有这些特征。有些可能构成大型存储库,供数据分析程序扫描。有些可能是运行应用程序不断生成的数据流。一些可能是存档数据。有些可能是在一台机器上产生的中间结果,在另一台机器上处理,无论是同时还是稍后。对于这种大文件的访问模式,追加成为性能优化和原子性保证的重点,而在客户端缓存数据块失去了吸引力

    4 第四,通过增加灵活性,共同设计应用程序和文件系统API有利于整个系统 .例如,我们放宽了GFS的一致性模型,从而极大地简化了文件系统,而不会给应用程序带来繁重的负担。我们还引入了原子追加操作,这样多个客户端可以并发地追加到一个文件,而不必在它们之间进行额外的同步。这些内容将在本文后面进行更详细的讨论

目前部署了多个GFS集群用于不同的目的。最大的存储节点超过1000个存储节点,超过300tb的磁盘存储,并且被不同机器上的数百个客户端连续地频繁访问。

2. DESIGN OVERVIEW

2.1 Assumptions 

1该系统是由许多经常失败的廉价商品组件构建而成的。它必须不断地监控自己,并在日常的基础上检测、容忍和迅速地从组件故障中恢复。

2系统存储一定数量的大文件。我们预计会有几百万个文件,每个文件的大小通常为100 MB或更大。多gb文件是常见的情况,应该有效地管理。小文件必须得到支持,但我们不需要为此进行优化。

3.工作负载主要由两种读操作组成:大的流读操作和小的随机读操作。在大型流媒体读取中,单个操作通常要读取数百个KBs,更常见的是1mb或更多。来自同一客户端的连续操作通常读取文件的连续区域。一个小的随机读取通常是在一些任意偏移处读取几个KBs。性能敏感的应用程序通常对小的读取进行批处理和排序,以稳定地在文件中前进,而不是来回移动

4工作负载还具有许多向文件追加数据的大型顺序写操作。典型的操作大小与读操作类似。文件一旦写入,就很少再被修改了。支持文件中任意位置的小写入,但不一定要高效。

2.2 Interface

GFS提供了一个熟悉的文件系统接口,尽管它没有实现POSIX等标准API。文件在目录中以层次结构组织,并由路径名标识。我们支持创建、删除、打开、关闭、读取和写入文件的常用操作。

此外,GFS具有快照和记录追加操作。快照以较低的成本创建文件或目录树的副本。Record append允许多个客户端同时向同一个文件追加数据,同时保证每个客户端追加的原子性。它对于实现多路合并结果和生产者消费者队列非常有用,许多客户端可以同时附加到这些队列中,而不需要额外的锁定。我们发现这些类型的文件在构建大型分布式应用程序时非常有用。快照和记录追加分别在第3.4节和3.3节中进一步讨论。

2.3 Architecture

AGFS集群由单个主服务器和多个chunkserver组成,由多个客户端访问,如图1所示。它们通常都是一台运行用户级服务器进程的商用Linux机器。在同一台机器上同时运行一个块服务器和一个客户端是很容易的,只要机器资源允许,并且运行可能不可靠的应用程序代码所导致的低可靠性是可以接受的.

文件被分成固定大小的块。每个块都由一个不可变的、全局唯一的64位块句柄来标识,该句柄是在块创建时由主机分配的。chunkserver将chunk以Linux文件的形式存储在本地磁盘上,并通过chunk句柄和字节范围来读写chunk数据。为了提高可靠性,每个块都被复制到多个块服务器上。默认情况下,我们存储三个副本,但是用户可以为文件名称空间的不同区域指定不同的复制级别。

主服务器维护所有文件系统元数据。这包括名称空间、访问控制信息、从文件到块的映射以及块的当前位置。它还控制系统范围的活动,如块租赁管理、孤立块的垃圾收集和块服务器之间的块迁移。master通过HeartBeat消息定期与每个chunkserver通信,给它指令并收集它的状态。

链接到每个应用程序中的GFS客户端代码实现了文件系统API,并与主服务器和chunkserver通信,以代表应用程序读写数据。客户端与主服务器进行元数据操作,但所有承载数据的通信都直接到chunkserver。我们不提供POSIX API,因此不需要挂接到Linux vnode层

客户端和chunkserver都不会缓存文件数据。客户端缓存几乎没有什么好处,因为大多数应用程序都要流经巨大的文件,或者工作集太大而无法缓存。不使用它们可以消除缓存一致性问题,从而简化客户端和整个系统。(然而,客户端缓存元数据。)chunkserver不需要缓存文件数据,因为块存储为本地文件,所以Linux的缓冲缓存已经将频繁访问的数据保存在内存中。

2.4 Single Master

拥有一个主主机极大地简化了我们的设计,并使主主机能够进行复杂的块放置.我们必须尽量减少它在读写中的参与,这样它就不会成为一个瓶颈。客户端从不通过主服务器读写文件数据。相反,客户端询问主服务器它应该联系哪些块服务器。它在有限的时间内缓存这些信息,并直接与chunkserver进行后续操作。

2.5 Chunk Size

块大小是关键的设计参数之一。我们选择了64mb,这比典型的文件系统块大小大得多。每个块副本以普通Linux文件的形式存储在块服务器上,并只在需要时进行扩展。延迟空间分配避免了内部碎片造成的空间浪费,这可能是反对如此大的块大小的最大障碍。大的块大小提供了几个重要的优势。首先,它减少了客户端与主块交互的需要,因为在同一个块上读写只需要向主块位置信息发出一次初始请求。这种减少对于我们的工作负载来说尤其重要,因为应用程序通常是按顺序读写大文件的。即使是小的随机读取,客户端也可以轻松地缓存多tb工作集的所有块位置信息。

2.6 Metadata

主存储三种主要类型的元数据:文件和块名称空间、从文件到块的映射以及每个块副本的位置。所有元数据都保存在主服务器的内存中。前两种类型(名称空间和文件到块的映射)也通过将变化记录到存储在主服务器本地磁盘上并复制到远程机器上的操作日志来保持持久化。使用aloga可以让我们简单、可靠地更新主状态,而且不会在主崩溃时出现不一致的风险。主服务器不持久地存储块位置信息。相反,它会在主启动时询问每个chunkserver关于它的块的信息,以及何时一个chunkserver加入集群。

2.7 Consistency Model

GFS有一个宽松的一致性模型,可以很好地支持我们的高度分布式应用程序,但实现起来仍然相对简单和高效。我们现在讨论GFS的保证以及它们对应用程序的意义。我们还强调了GFS如何维护这些保证,但将细节留给本文的其他部分。

3. SYSTEM INTERACTIONS

我们设计这个系统是为了尽量减少master参与所有操作。在此背景下,我们现在描述客户端、主服务器和chunkserver如何交互来实现数据突变、原子记录追加和快照

3.1 Leases and Mutation Order

突变是一种改变块的内容或元数据的操作,如写或追加操作。每个突变都在所有块的副本上执行。我们使用租赁来保持副本间一致的突变顺序。主节点向其中一个副本授予一块租约,我们称之为主节点。主序列为数据块的所有突变选择一个序列顺序。当应用突变时,所有的复制体都遵循这个顺序。因此,全局突变顺序首先由主节点选择的租期授予顺序定义,在租期中由主节点分配的序列号定义。

租赁机制的设计目的是使主服务器的管理开销最小化。租约的初始超时时间为60秒。然而,只要块发生变化,主节点就可以请求并接收主节点的扩展。这些扩展请求和授权是在主块服务器和所有块服务器之间定期交换的HeartBeat消息上承载的。主服务器有时可能试图在租约到期前撤销租约(例如,当主服务器希望禁用正在重命名的文件的突变时)。即使主服务器失去了与主服务器的通信,它也可以在旧的租约到期后安全地将新租约授予另一个副本。

3.2 Data Flow

我们将数据流与控制流解耦,以有效地使用网络。当控制流从客户端到主服务器,然后到所有的辅助服务器时,数据以流水线的方式沿着精心挑选的块服务器链线性推送。我们的目标是充分利用每台机器的网络带宽,避免网络瓶颈和高延迟链接,并最大限度地减少通过所有数据的延迟。

3.3 Atomic Record Appends

GFS提供了一个称为记录追加的原子追加操作。在传统的写操作中,客户端指定要写入数据的偏移量。并发写入同一区域是不可序列化的:该区域最终可能包含来自多个客户端的数据片段。然而,在记录追加中,客户端只指定数据。在GFS选择的偏移量处,GFS至少原子地将其追加到文件中一次(即一个连续的字节序列),并将该偏移量返回给客户端。这类似于在Unix中以O APPEND模式打开的文件,在没有竞争条件的情况下,当多个写入器并发地这样做时。我们的分布式应用程序大量使用记录追加,其中不同机器上的许多客户端并发地追加到同一文件。

3.4 Snapshot

快照操作几乎在瞬间复制文件或目录树(源代码),同时最小化正在进行的突变的任何中断。我们的用户使用它来快速创建巨大数据集的分支副本(通常是递归地复制这些副本),或者在试验可以稍后轻松提交或回滚的更改之前检查当前状态。

4. MASTER OPERATION

主服务器执行所有命名空间操作。此外,它在整个系统中管理块副本:它做出布局决策,创建新的块和副本,并协调各种系统范围的活动,以保持块完全复制,平衡所有块服务器的负载,并回收未使用的存储。我们现在讨论每一个主题。

5. FAULT TOLERANCE AND DIAGNOSIS

设计系统的最大挑战之一是处理频繁的组件故障。组件的数量加在一起,使这些问题更常见而不是例外:我们不能完全信任机器,也不能完全信任磁盘。组件故障可能导致系统不可用,更糟糕的是,可能导致数据损坏。我们将讨论如何应对这些挑战,以及我们在系统中构建的用于在不可避免地出现问题时诊断问题的工具。

5.1 High Availability

在GFS集群中的数百台服务器中,某些服务器在任何给定时间都不可用。我们通过两个简单而有效的策略来保持整个系统的高可用性:快速恢复和复制。

5.1.1 Fast Recovery

master和chunkserver都被设计用来恢复它们的状态,并且不管它们是如何终止的,都在几秒钟内启动。事实上,我们并不区分正常终止和异常终止;服务器通常通过终止进程来关闭。客户端和其他服务器在其未完成的请求超时、重新连接到重新启动的服务器并重试时,会遇到一个小故障

5.1.2 Chunk Replication

如前所述,每个块都被复制到不同机架上的多个块服务器上。用户可以为文件命名空间的不同部分指定不同的复制级别。默认值是3。当块服务器离线或通过校验和验证检测损坏的副本时,主克隆现有的副本需要保持每个块完全复制(参见5.2节)。虽然复制已经为我们提供了很好的服务,但我们正在探索其他形式的跨服务器冗余,例如奇偶校验或擦除代码,以满足日益增长的只读存储需求。我们认为,在我们非常松散耦合的系统中实现这些更复杂的冗余方案是具有挑战性的,但也是可控的,因为我们的流量主要由追加和读取控制,而不是小的随机写操作。

5.1.3 Master Replication

为了保证可靠性,主状态被复制。它的操作日志和检查点被复制到多台机器上只有在将状态的变化的日志记录刷新到本地磁盘和所有主副本后,才会认为已提交状态变化。为了简单起见,一个主进程仍然负责所有的变化以及后台活动,比如在内部更改系统的垃圾收集。当它失败时,它几乎可以立即重新启动。如果GFS的机器或磁盘发生故障,则监视GFS外部的基础设施将在别处启动一个新的主进程,并使用复制的操作日志。客户端只使用主机的规范名称(例如gfs-test),这是一个DNS别名,如果主机被重新定位到另一台机器,可以更改这个别名。

6. MEASUREMENTS

在本节中,我们将介绍一些微基准测试,以说明GFS体系结构和实现中的固有瓶颈,以及来自谷歌中实际使用的集群的一些数据

6.1 Micro-benchmarks

我们测量了GFS集群的性能,该集群由一个主服务器、两个主副本、16个块服务器和16个客户端组成。注意,设置这个配置是为了便于测试。典型的集群有数百个块服务器和数百个客户端

所有机器都配置了双1.4 GHz PIII处理器,2gb内存,两个80gb 5400 rpm磁盘,以及100mbps全双工以太网连接到HP 2524交换机。所有19台GFS服务器机器连接到一个交换机,所有16台客户端机器连接到另一个交换机。两台交换机以1gbps链路连接。

6.1.1 Reads

N个客户端同时从文件系统读取数据。每个客户端从320gb的文件集中读取一个随机选择的4mb区域。此操作重复256次,以便每个客户机最终读取1 GB的数据。这些块服务器总共只有32gb的内存,所以我们预计在Linux缓存中最多有10%的命中率。我们的结果应该接近冷缓存的结果。

当两个交换机之间的1gbps链路饱和时,最大值为125mb /s,或者当每个客户端100mbps网络接口饱和时,最大值为12.5 MB/s。当只有一个客户端在读取时,观察到的读取速率是10mb /s,或每个客户端限制的80%。当有16个读取器时,即每个客户端有6mb /s的读取速率,达到了125mb /s链路限制的75%,达到了94mb /s。效率从80%下降到75%,因为随着读取器数量的增加,多个读取器同时从同一块服务器读取数据的概率也会增加。

6.1.2 Writes

N个客户端同时写入N个不同的文件。每个客户端在一系列1mb的写操作中向一个新文件写入1gb的数据。累计写速率及其理论极限如图3(b)所示。这个限制稳定在67 MB/s,因为我们需要将每个字节写入16个chunkserver中的3个,每个都有一个12.5 MB/s的输入连接。

一个客户端写速率为6.3 MB/s,大约是限制的一半。造成这种情况的主要原因是我们的网络堆栈。它不能很好地与我们用于将数据推送到块副本的流水线模式进行交互。将数据从一个副本传播到另一个副本的延迟降低了总体写速率。

9. CONCLUSIONS

谷歌文件系统展示了在商用硬件上支持大规模数据处理工作负载所必需的特性。虽然一些设计决策是针对我们独特的环境,但许多可能适用于类似规模和成本意识的数据处理任务。我们首先根据当前和预期的应用程序工作负载和技术环境重新检查传统的文件系统假设。我们的观察导致了设计空间中截然不同的观点。我们将组件失败视为规范而不是异常,优化那些大部分被追加(可能是并发的)然后读取(通常是顺序的)的巨大文件,并且扩展和放松标准文件系统接口,以改进整个系统。

我们的系统通过持续监控、复制关键数据和快速自动恢复来提供容错功能。块复制允许我们容忍chunkserver failures.这些故障的频率激发了一种新颖的在线修复机制,它定期和透明地修复损坏,并尽快补偿丢失的副本。此外,我们使用校验和来检测磁盘或IDE子系统级别的数据损坏,考虑到系统中的磁盘数量,这种情况非常常见。

我们的设计为执行各种任务的许多并发读取器和写入器提供了高的总吞吐量。我们通过将文件系统控制(它通过主服务器)与数据传输(它直接在块服务器和客户端之间传递)分离来实现这一点。通过较大的块大小和块租赁(在数据突变时将权限委托给主副本),可以将主服务器对常用操作的参与最小化。这使得简单、集中的主服务器成为可能,而不会成为瓶颈。我们相信,我们的网络栈的改进将解除当前对单个客户机的写吞吐量的限制。

GFS已成功满足了我们的存储需求,并作为研发和生产数据处理的存储平台广泛应用于谷歌。它是一个重要的工具,使我们能够在整个网络的规模上继续创新和解决问题。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值