002.精读《The Google File System》| 大数据的三驾马车之一:GFS

1. 引言

本期,我们将精读一篇极具分量的论文——《The Google File System》。这篇文章不仅为大数据存储和管理提供了开创性的视角,更成为了整个大数据架构的三大支柱之一。GFS的设计哲学和实现细节,对于理解现代大规模数据处理的复杂性至关重要。
在接下来的内容中,我们将一起:

  • 剖析GFS的核心架构和设计原则。
  • 探讨GFS如何应对大规模数据集的存储和访问挑战。
  • 评估GFS在大数据生态系统中的地位和影响。
  • 展望GFS理念在未来发展中的演变和应用前景。

无论您是大数据领域的资深研究者,还是刚刚踏上数据科学之旅的新手,让我们一同启程,深入大数据的心脏地带,探索GFS的奥秘。

2. 精读

2.1 摘要

摘要部分介绍了GFS(Google文件系统)的核心设计目标和关键特性。它强调了该系统如何有效处理大量分布式、容错和可扩展的数据存储需求,以支持Google的大规模数据处理应用程序。系统设计包括了容错性、性能优化和可扩展性等方面,适用于在数千台通用硬件设备上运行的大规模应用程序。

“The Google File System (GFS) is a scalable distributed file system for large distributed data-intensive applications. It provides fault tolerance while running on inexpensive commodity hardware, and it delivers high aggregate performance to a large number of clients. While sharing many of the same goals as previous distributed file systems, our design has been driven by observations of our application workloads and technological environment, both current and anticipated, that reflect a marked departure from some earlier file system assumptions.”

目标:我们设计并实现了Google文件系统,这是一个可扩展的分布式文件系统,适用于大型分布式数据密集型应用 。

We discuss many aspects of our design, report measurements from both micro-benchmarks and real-world use, ……explore radically different design points.

强调:GFS的最大优势在于其已经在实际应用中得到验证,并且与现有的其他大数据系统相比,它能够在成本较低的硬件上持续高效地处理数据。

是否真的如摘要说的那般神奇?让我们继续深入探索,揭开GFS的神秘面纱,一探究竟。

2.2 背景

在介绍部分,GFS(Google 文件系统)被设计和实现是为了满足 Google 快速增长的数据处理需求。虽然 GFS 和之前的分布式文件系统有许多相同的目标,如性能、可扩展性、可靠性和可用性,但其设计基于对当前和未来应用工作负载及技术环境的观察,这些观察与早期的文件系统设计假设有显著不同。

  • 组件故障: 故障是常态,而非例外。
  • 文件大小: 文件通常比传统标准大得多。
  • 数据修改: 大多数文件是通过追加新数据来修改,而不是覆盖已有数据
  • 应用与文件系统 API 的共同设计: 共同设计应用程序和文件系统 API 可以提高系统的整体灵活性。
  1. First, component failures are the norm rather than the exception.
  2. Second, files are huge by traditional standards.
  3. Third, most files are mutated by appending new data rather than overwriting existing data.
  4. Fourth, co-designing the applications and the file system API benefits the overall system by increasing our flexibility.

因此,GFS 重新审视了传统的设计选择,并探索了设计空间中的全新方向。GFS 的设计一个重要前提是:组件故障是常态而非例外。因此,Google就放宽了对一致性的传统要求,转而采用一种更加灵活的策略。同时,小吹一下其文件系统已经在实际的大规模应用,进而证明自己的实力和可靠性。

For example, we have relaxed GFS’s consistency model to vastly simplify the file system without imposing an onerous burden on the applications.
Multiple GFS clusters are currently deployed for different purposes. The largest ones have over 1000 storage nodes, over 300 TB of disk storage, and are heavily accessed by hundreds of clients on distinct machines on a continuous basis.

2.3 系统架构

针对上述观察,我们发现它们与早期文件系统的设计假设存在显著差异。为此,我们采取了以下解决方案:

  • 组件故障:我们接受故障为常态,系统设计以自我监控和快速恢复为原则,适应低成本硬件环境下的持续运行。
  • 文件规模:主要是文件大小超100MB。小文件兼容,不做优先。
  • 数据修改:倾向于追加而非覆盖,优化大规模顺序写入,随机写入仅有效支持。
  • API协同设计:应用程序与文件系统API的深度整合,提升了系统灵活性。我们重视持续高带宽,满足大规模数据处理需求,而非单一操作的低延迟。优先支持高吞吐优而非低延时。

GFS采用了一个Master节点和多个chunkserver节点的构成,Master节点负责维护整个文件系统的元数据,而实际的文件数据则以chunk为单位(块的大小固定不变,64字节)分散存储在各个chunkserver节点上(默认情况下,我们存储3个副本)。每个chunk都拥有一个独一无二的句柄(handle),这使得它们能够被Master节点准确识别。

The master maintains all file system metadata. This includes the namespace, access control information, the mapping from files to chunks, and the current locations of chunks. It also controls system-wide activities such as chunk lease management, garbage collection of orphaned chunks, and chunk migration between chunkservers. The master periodically communicates with each chunkserver in HeartBeat messages to give it instructions and collect its state.

Master节点负责维护所有的文件系统元数据,包括命名空间、访问控制信息、文件到数据块的映射以及数据块的当前存储位置。此外,它还控制系统级别的活动,如数据块租约管理、孤立数据块的垃圾回收和数据块在服务器之间的迁移。主节点会定期通过心跳消息与每个数据块服务器通信,以下达指令并收集状态信息。

客户端与文件数据的交互并不是直接通过Master节点进行的。相反,它采取了一种更为智能和间接的方式:客户端首先向Master节点发起询问,以获取需要联系的chunkserver节点信息。Master节点根据当前的文件系统状态和chunk分布情况,向客户端指明哪些chunkserver节点持有所需的数据块。

GFS的读取操作流程极为简洁:

  1. 客户端请求:客户端向Master节点发送请求,提供所需文件的名称和数据的偏移量。

  2. Master响应Master节点根据请求,回复客户端chunk的句柄和包含目标chunkchunkserver地址列表。客户端将这一结果缓存,以备后续使用。

  3. 客户端发起读取:客户端根据Master提供的信息,选择最近的chunkserver发起读取请求。

  4. chunkserver响应:被请求的chunkserver将请求的数据发送回客户端。

GFSchunk size设定为64MB,这一尺寸显著超越了传统文件系统的block size。这种设计选择带来了以下益处:首先,它减少了客户端与Master节点交互的需要。其次,它可以降低网络开销。第三,它减少了存储在Master节点上的元数据大小。

  1. First, it reduces clients’ need to interact with the master.
  2. Second, it can reduce network overhead.
  3. Third, it reduces the size of the metadata stored on the master.

Master节点负责维护三种关键类型的元数据,它们构成了GFS架构的核心:

  1. 文件和块的命名空间Master节点存储了文件系统的命名空间信息,这包括所有文件和目录的层次结构和名称。
  2. 文件到块的映射Master节点管理着从文件到存储块的映射关系,确保每个文件的数据能够被准确地定位到对应的chunk
  3. 块副本的位置信息Master节点还记录了每个chunk的副本位置信息,这涉及到数据的冗余存储和分布式部署,以确保数据的高可用性和容错性。

The first two types (namespaces and file-to-chunk mapping) are also kept persistent by logging mutations to an operation log stored on the master’s local disk and replicated on remote machines.

GFS中,命名空间和文件到chunk的映射这两种元数据是至关重要的,它们会被持久化存储到磁盘。任何对这些元数据的修改都会被详细记录在操作日志中,确保了数据变更的持久性和可审计性。

与此相反,chunk副本的位置信息则不会持久化存储。当Master节点启动或有新的chunkserver节点加入集群时,Master节点会主动与chunkserver节点通信,动态获取这些信息。

Master节点通过定期与chunkserver节点的心跳检测来获取chunk的位置信息,而不是将这些信息持久化存储。这种设计选择背后的原因是:

A chunkserver has the final word over what chunks it does or does not have on its own disks.

  • 复杂性管理:如果选择持久化chunk位置信息,Master节点就需要不断同步与chunkserver节点之间的数据,以保持一致性。这在chunkserver节点频繁进行扩缩容、故障转移(failover)、重命名等操作时,会变得相当复杂。

  • 权威性来源chunkserver节点直接管理着存储在本地的chunk,因此它们拥有关于chunk位置和状态的最终话语权。例如,在chunk损坏或出现其他问题时,只有chunkserver节点能够提供最准确和及时的信息。

Not only is it the only persistent record of metadata, but it also serves as a logical timeline that defines the order of concurrent operations.

operation log不仅元数据的唯一持久记录,还充当了一个逻辑时钟,为系统内发生的事件提供了一个统一的时间戳序。

  • 一致性:当一个文件区域被修改后,如果所有客户端无论访问哪个副本(replica)都能看到相同的状态,这个区域就被认为是一致的。

  • 确定性:如果客户端不仅能看到一致的状态,还知道修改后的具体内容,那么这个状态就被称为确定的。

GFS has a relaxed consistency model that supports our highly distributed applications well but remains relatively simple and efficient to implement.

GFS对于一致性实现比较宽松,GFS通过以下机制确保文件区域在多次成功修改后保持确定性:

  1. 修改顺序:所有副本按照相同的顺序应用修改,确保了全局的一致性。

  2. 版本控制:使用chunk版本号来识别哪些副本已经过时,这些过时的副本将不会参与后续的读写操作,并最终被垃圾回收机制清除。

尽管存在一个小的时间窗口,客户端的缓存可能使其读取到过时的数据,但这种情况很少发生,因为:

  • 缓存更新:客户端通常会在缓存过期前与Master节点通信,以获取最新的chunk位置信息。

  • 副本恢复Master节点会在副本损坏或过时后迅速恢复新的副本,除非在极短的时间内所有副本都损坏了。即使在这种情况下,数据也只是丢失而不是被错误地写入,应用程序可以接收到确定的异常信号,而不是错误的数据。

本章节详细描述了GFS的架构,包括主服务器和块服务器如何协同工作以及元数据管理。

2.4 交互流程

GFS通过数据版本号来确保数据的一致性。Master节点负责记录每个chunk的最新数据版本。当客户端需要访问chunk时,Master节点将只指向那些持有最新版本数据的chunkserver

租约机制

租约是GFS中用于管理数据版本的核心技术。通过租约Master节点在chunkserver中选定一个primary服务器,其余则作为secondary服务器。租约具有时间限制,一旦租约到期,Master节点必须建立新的租约并递增版本号。

We use leases to maintain a consistent mutation order across replicas.

租约的达成流程

  1. Master节点根据chunk句柄获取chunk的最新数据版本号。
  2. 筛选出拥有该chunk最新版本的chunkserver
  3. 从筛选结果中选择一个chunkserver作为primary,其余作为secondary
  4. 更新版本号,并将最新版本号通知给primarysecondaries
  5. 将最新的版本号持久化存储。

租约的有效期的重要性

GFS集群中对于每个chunk只允许存在一个primary租约的有效期确保了这一规则的执行。如果租约没有时间限制,那么在发生网络分区(即“裂脑”错误)时,如果Master节点没有收到primary的心跳信号,可能会错误地判断primary已经失效并指定新的primary。这种情况下,如果原始的primary仍然在运行并处理请求,就可能导致数据不一致。

通过设置租约的有效期,即使在心跳信号丢失的情况下,Master节点也会等待当前租约过期,确保原来的primary失去服务资格后,才会重新指定新的primary。这一机制保障了在任何时刻,对于特定的chunk,集群中只有一个有效的primary,从而维护了数据的一致性。

GFS的写操作流程

在GFS中,写操作是以chunk为基本单位进行的。如果客户端需要写入的数据量超过了单个chunk的大小,或者写入的范围跨越了多个chunk,那么这些操作将被自动分割成多次独立的写操作。为了最大化网络带宽的利用率,写操作被划分为两个流程:控制流和数据流。控制流负责向Masterprimary传递写入指令,而数据流则负责将待写入的数据传输到目标chunkserver的缓冲区。

完整的写入过程如下

  1. 客户端向Master请求租约(如果尚未存在,则创建);
  2. Master向客户端提供租约中的primarysecondaries(此时如果这个chunk没有primarymaster会临时授予一个,此信息被客户端缓存);
  3. 客户端将数据发送到primarysecondaries的缓冲区(LRU队列),但数据尚未真正写入;
  4. 客户端向primary发送写指令,primary为所有它收到还未处理的数据分配sequence number,并在本地执行修改。
  5. 转发给所有replica,每个replica按相同顺序执行这些写请求,primary将数据从缓冲区写入到secondaries的硬盘上;
  6. 如果上一步的写入操作全部成功,secondary回复primaryprimary回复clientprimary回复成功;如果失败,回复失败并提示客户端进行重试。

本章及主要详细描述了客户端、主服务器和块服务器之间的交互过程。

2.5 主节点操作

前面提了Master节点负责维护三种关键类型的元数据,它们构成了GFS架构的核心:

  1. 文件和块的命名空间Master节点存储了文件系统的命名空间信息,这包括所有文件和目录的层次结构和名称。
  2. 文件到块的映射Master节点管理着从文件到存储块的映射关系,确保每个文件的数据能够被准确地定位到对应的chunk
  3. 块副本的位置信息Master节点还记录了每个chunk的副本位置信息,这涉及到数据的冗余存储和分布式部署,以确保数据的高可用性和容错性。

命名空间管理和锁定
GFS并未采用树形结构来维护命名空间(namespace),而是将所有命名空间保存在一个表中。表中每条记录的键(key)是文件的完整路径,例如/d1/d2/…/dn/leaf,它对应着/d1/d1/d2/d1/d2/…/dn/leaf等一系列路径。每条记录都对应一个读写锁。在访问某个路径时,需要持有其所有前缀记录的读锁。创建文件时,不需要持有前缀记录的写锁,仅读锁就足以保证前缀记录不被删除。

这种设计的一个显著优点是它允许在同一个目录内并发地进行修改。

The master uses a simple locking mechanism over the namespace to ensure proper serialization of concurrent operations.

副本放置
chunk的副本位置策略服务于两个主要目的:

  • 最大化数据的可靠性和可用性;
  • 最大化网络带宽的利用率。

因此,副本会被分布在不同机架(rack)的机器上,这样即使某个机架出现问题,也不容易导致整个chunk数据丢失,同时也有利于在读取时充分利用整个机架的网络带宽。这种策略的代价是在写入时数据需要流经多个机架。

The master places replicas based on several factors including reliability, availability, network topology, and load balancing.

创建、重新复制、平衡
在新创建chunk时,位置选择会考虑以下因素:

  • 优先选择磁盘空闲的chunkserver
  • 控制每个chunkserver上新创建的chunk数量,避免后续流量集中于单一chunkserver
  • chunk分散在不同的机架上。

一旦Master发现某个chunk的副本数量减少,就会触发重新复制(re-replication)。它的优先级取决于缺少的副本数量、chunk的活跃度,以及是否阻塞了客户端请求。

Master还会定期执行平衡操作(rebalancing),但不会一次性填满新加入的chunkserver,而是采取渐进式的方法。

When a new chunk is created, the master allocates storage space for its replicas.

垃圾回收
当文件被删除时,Master首先在操作日志(operation log)中记录,然后将文件重命名为包含删除时间戳的隐藏文件。之后,Master会定期扫描这些文件,超过一定天数未删除的文件将被真正删除。Master在给chunkserver的心跳回复中会包含需要删除的chunk列表。

he master periodically scans and removes orphaned chunks.

通过这种异步的、基于状态对比的、批量通知的方式,GFS的垃圾回收可以处理多种情况下的垃圾,简化了流程,并且分摊了开销。其缺点是回收存在一定的延迟。补救措施包括:隐藏文件被删除时会立即执行删除、用户可以指定强制删除、用户可以指定某个路径下的文件不参与复制。

过期副本检测
对于每个chunkMaster维护了一个版本号(version),每次授予租约(lease)时版本号增加,并且Master和副本都会持久化这个版本号。如果Master遇到了比自己记录的版本号更大的版本号,可能是因为Master之前进行了故障转移(failover),此时Master会提升自己记录的版本号;如果遇到了更小的版本号,则认为该副本已过期,成为垃圾数据。

he master maintains a version number to detect stale replicas.

在回复客户端关于副本位置的请求时,Master也会带上这个版本号,从而避免客户端访问过期的副本。

2.6 容错与诊断

高可用性
Masterchunkserver在退出时不区分是正常还是意外,都采用统一的快速恢复流程,确保系统的高可用性。

The master is designed to handle failures and is restarted quickly.

数据块复制

  • 不同的namespace可以设置不同的复制级别。
  • Master会迅速复制那些副本不足的chunk

冗余方案探索
GFS正在探索使用奇偶校验码、纠删码等其他冗余方案,这主要是基于GFS场景中追加操作和读取操作远多于小块随机写入的特点。

Master复制

  • Master的修改在自身及其所有副本的operation log持久化后才视为提交成功。

  • Master的副本被称为shadow而非mirror,它们的状态可能会稍微落后于primary,但也能提供非最新数据的读取能力。

  • shadow replica也会按照与primary相同的顺序执行修改,并从chunkserver获取chunk列表。只有新创建的chunk和被回收的chunk需要从primary处获得信息。

数据完整性
由于GFS集群可能包含大量磁盘,磁盘错误是常有的事,但逐一比较每个chunk副本是不现实的,且不同副本间也可能存在不一致性。因此,chunkserver通过checksum来验证chunk的正确性。

Each chunkserver uses checksums to detect corruption.

  • 每个chunkblock都有对应的checksum,这些checksum存储在内存中,在读取时进行校验。这对性能的影响很小,因为校验checksum不涉及I/O操作,而计算checksum的开销可以被I/O操作所分摊。

  • 客户端会根据block大小对齐读取范围。

  • 在追加写入时,直接基于旧的checksum计算新的checksum。如果之前这个block已经不一致,checksum将不匹配,在后续读取时会发现问题。

  • 覆盖写入需要读取整个范围的block并重新计算checksum

  • chunkserver在空闲时会挑选一些不活跃的chunk进行数据校验。

同时也构建了广泛的诊断工具来监控 GFS 集群。

We have built extensive diagnostic tools to monitor GFS clusters.

通过这些机制,GFS确保了数据的高可用性和完整性,即使在面对磁盘错误和其他挑战时也能有效维护数据的稳定性和可靠性。

3. 总结

首先,GFS(Google文件系统)向我们展示了如何在成本效益高的硬件上实现高效的故障容错和数据一致性。它尤其擅长处理大规模数据集,通过精心设计的租约机制和数据流优化,有效地管理数据副本并确保操作的原子性。

此外,我深入了解了如何通过简化的命名空间锁定策略来有效管理并发操作,这不仅提升了系统的整体可用性,也使得在多用户环境下的文件操作更加安全和可靠。

GFS的设计还特别强调了通过定期快照和记录追加操作来提升数据处理的效率和安全性,这一点对于维护大型数据集的完整性至关重要。

数据完整性是另一个关键的收获。GFS通过校验和(checksum)机制,能够及时检测并修复数据损坏,这种对数据完整性的持续关注显著增强了系统在面对硬件故障时的稳定性和健壮性。

最后,由于篇幅限制,一些数据验证的深入讨论并未在此展开。对于有兴趣进一步探索的读者,我建议精读全文以获得更全面的了解。

获取原文


如果你想参与讨论,请 点击这里,每周都有新的主题,周末或周一发布。

大数据精读,探索知识的深度。

关注 大数据精读周刊 微信公众号

版权声明:自由转载-非商用-非衍生-保持署名(创意共享 3.0 许可证

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大数据精读周刊

喝杯咖啡????

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值