分布式系统:The Google File System(GFS)学习摘要

标签:
gfs分布式大数据云计算 |
分类: JAVA高级软件工程师 |
一个面向大规模数据密集型应用的、可伸缩的分布式文件系统。
1.假设:
1).组件失效时常态。
2).文件非常巨大
3).绝大部分文件的修改是采用在文件尾部追加数据
4).应用程序和文件系统API的协同设计提高了整个系统的灵活性
2.设计概述
2.1设计预期
2.2 接口
创建新文件、删除文件、打开文件、关闭文件、读和写文件。
GFS提供了快照和记录追加操作
2.3 架构
一个GFS集群包含一个单独的Master节点、多台 Chunk服务器,并且同时被多个客户端访问,如图1所示。
http://s6/mw690/001soofhty6OFb4sQlv45&690Google
GFS存储的文件都被分割成固定大小的Chunk。在Chunk创建的时候,Master服务器会给每个Chunk分配一个不变的、全球唯一的 64位的Chunk标识。Chunk服务器把Chunk以linux文件的形式保存在本地硬盘上,并且根据指定的Chunk标识和字节范围来读写块数据。 出于可靠性的考虑,每个块都会复制到多个块服务器上。缺省情况下,我们使用3个存储复制节点,不过用户可以为不同的文件命名空间设定不同的复制级别。
Master节点管理所有的文件系统元数据。这些元数据包括名字空间、访问控制信息、文件和Chunk的映射信息、以及当前Chunk的位置信息。Master节点还管理着系统范围内的活动,比如,Chunk租用管理 (alex注:BDB也有关于lease的描述,不知道是否相同)、孤儿Chunk (alex注:orphaned chunks)的回收、以及Chunk在Chunk服务器之间的迁移。Master节点使用心跳信息周期地和每个Chunk服务器通讯,发送指令到各个Chunk服务器并接收Chunk服务器的状态信息。
GFS客户端代码以库的形式被链接到客户程序里。客户端代码实现了GFS文件系统的API接口函数、应用程序与Master节点和Chunk服 务器通讯、以及对数据进行读写操作。客户端和Master节点的通信只获取元数据,所有的数据操作都是由客户端直接和Chunk服务器进行交互的。我们不 提供POSIX标准的API的功能,因此,GFS API调用不需要深入到Linux vnode级别。
无论是客户端还是Chunk服务器都不需要缓存文件数据。客户端缓存数据几乎没有什么用处,因为大部分程序要么以流的方式读取一个巨大文件,要 么工作集太大根本无法被缓存。无需考虑缓存相关的问题也简化了客户端和整个系统的设计和实现。(不过,客户端会缓存元数据。)Chunk服务器不需要缓存 文件数据的原因是,Chunk以本地文件的方式保存,Linux操作系统的文件系统缓存会把经常访问的数据缓存在内存中。
2.4 单一Master节点
单一的Master节点可以通过全局的信息精确定位Chunk的位置以及进行复制决策。
简单读取的流程。首先,客户端把文件名和程序指定的字节偏移,根据固定的Chunk大小,转换成文件的Chunk索 引。然后,1)它把文件名和Chunk索引发送给Master节点。2)Master节点将相应的Chunk标识和副本的位置信息发还给客户端。客户端用文件名和 Chunk索引作为key缓存这些信息。3)之后客户端发送请求到其中的一个副本处,一般会选择最近的。请求信息包含了Chunk的标识和字节范围。在对这个Chunk的后续读取操作中, 客户端不必再和Master节点通讯了,除非缓存的元数据信息过期或者文件被重新打开。
2.5 Chunk尺寸
64MB
优点:它减少了客户端和Master节点通讯的需求;少了Master节点需要保存的元数据的数量
2.6 元数据
Master服务器存储3种主要类型的元数据,包括:文件和Chunk的命名空间、文件和Chunk的对应关系、每个Chunk副本的存放地点。所有的元数据都保存在 Master服务器的内存中。
记录变更日志的方式记录在操作系统的系统日志文件中.
2.6.1 内存中的数据结构
2.6.2 Chunk位置信息
启动的时候轮询Chunk服务器,之后定期轮询更新的方式更简单
2.6.3 操作日志
操作日志包含了关键的元数据变更历史记录.操作日志是元数据唯一的持久化存储记录,它也作为判断同步操作顺序的逻辑时间基线(
Master服务器在日志增长到一定量时对系统状态做一次Checkpoint,将所有的状态数据写入一个Checkpoint文件.
2.7 一致性模型
GFS支持一个宽松的一致性模型,这个模型能够很好的支撑我们的高度分布的应用,同时还保持了相对简单且容易实现的优点。
2.7.1 GFS一致性保障机制
数据修改后文件region的状态取决于操作的类型、成功与否、以及是否同步修改。
经过了一系列的成功的修改操作之后,GFS确保被修改的文件region是已定义的,并且包含最后一次修改操作写入的数据。GFS通过以下措施确保 上述行为:(a) 对Chunk的所有副本的修改操作顺序一致(3.1章),(b)使用Chunk的版本号来检测副本是否因为它所在的Chunk服务器宕机(4.5章)而错 过了修改操作而导致其失效。
2.7.2 程序的实现
尽量采用追加写入而不是覆盖,Checkpoint,自验证的写入操作,自标识的记录(记录的唯一标识符)。
3. 系统交互
我们在设计这个系统时,一个重要的原则是最小化所有操作和Master节点的交互。带着这样的设计理念,我们现在描述一下客户机、Master服务器和Chunk服务器如何进行交互,以实现数据修改操作、原子的记录追加操作以及快照功能。
3.1 修改--->租约(lease)和变更顺序
变更是一个会改变Chunk内容或者元数据的操作,比如写入操作或者记录追加操作。变更操作会在Chunk的所有副本上执行。我们使用租约 (lease)机制来保持多个副本间变更顺序的一致性。Master节点为Chunk的一个副本建立一个租约,我们把这个副本叫做主Chunk。主 Chunk对Chunk的所有更改操作进行序列化。所有的副本都遵从这个序列进行修改操作.
3.2 数据流
为了提高网络效率,我们采取了把数据流和控制流分开的措施。
在控制流从客户机到主Chunk、然后再到所有二级副本的同时,数据以管道的方式, 顺序的沿着一个精心选择的Chunk服务器链推送。
3.3 原子的记录追加
记录追加是一种修改操作,它也遵循3.1节描述的控制流程,除了在主Chunk有些额外的控制逻辑.。主Chunk会检查这次记录追加操作是否会使Chunk超过最大尺寸(64MB)。
3.4 快照
快照操作几乎可以瞬间完成对一个文件或者目录树(“源”)做一个拷贝,并且几乎不会对正在进行的其它操作造成任何干扰。
我们用标准的copy-on-write技术实现快照。做快照;有新的客户请求时,复制一份新的,请求操作新的。
4. Master节点的操作
Master节点执行所有的名称空间操作。此外,它还管理着整个系统里所有Chunk的副本:它决定Chunk的存储位置,创建新Chunk和 它的副本,协调各种各样的系统活动以保证Chunk被完全复制,在所有的Chunk服务器之间的进行负载均衡,回收不再使用的存储空间。本节我们讨论上述 的主题。
4.1 名称空间管理和锁(读取锁、写锁)
逻辑上,GFS的名称空间就是一个全路径和元数据映射关系的查找表。
们允许多个操作同时进行,使用名称空间的region上的锁来保证执行的正确顺序。
因为名称空间可能有很多节点,读写锁采用惰性分配策略,在不再使用的时候立刻被删除。同样,锁的获取也要依据一个全局一致的顺序来避免死锁:首先按名称空间的层次排序,在同一个层次内按字典顺序排序。
4.2 副本的位置
有数百个Chunk服务器安装在许多机架上。
Chunk副本位置选择的策略服务两大目标:最大化数据可靠性和可用性,最大化网络带宽利用率。
了实现这两个目的,仅仅是在多台机器上分别存 储这些副本是不够的。我们必须在多个机架间分布储存Chunk的副本。
4.3 创建,重新复制,重新负载均衡
Chunk的副本有三个用途:Chunk创建,重新复制和重新负载均衡。
选择新副本的位置的策略和 创建时类似:平衡硬盘使用率、限制同一台Chunk服务器上的正在进行的克隆操作的数量、在机架间分布副本。
Master服务器周期性地对副本进行重新负载均衡:它检查当前的副本分布情况,然后移动副本以便更好的利用硬盘空间、更有效的进行负载 均衡。
4.4 垃圾回收
GFS在文件删除后不会立刻回收可用的物理空间。GFS空间回收采用惰性的策略,只在文件和Chunk级的常规垃圾收集时进行。
4.4.1 机制
当一个文件被应用程序删除时,Master节点象对待其它修改操作一样,立刻把删除操作以日志的方式记录下来。但是,Master节点并不马上回收资源,而是把文件名改为一个包含删除时间戳的、隐藏的名字。当Master节点对文件系统命名空间做常规扫描的时候,它会删除所有三天前的隐藏文件。
4.4.2 讨论
简单可靠;垃圾回收把存储空间的回收操作合并到Master节点规律性的后台活动中;延缓存储空间回收为意外的、不可逆转的删除操作提供了安全保障。
4.5 过期失效的副本检测
当Chunk服务器失效时,Chunk的副本有可能因错失了一些修改操作而过期失效。Master节点保存了每个Chunk的版本号,用来区分当前的副本和过期副本。
5. 容错和诊断
最大挑战之一是如何处理频繁发生的组件失效。
5.1 高可用性
在GFS集群的数百个服务器之中,在任何给定的时间必定会有些服务器是不可用的。我们使用两条简单但是有效的策略保证整个系统的高可用性:快速恢复和复制。
5.1.1 快速恢复
它们都被设计为可以在数秒钟内恢复它们的状态并重新启动。
5.1.2 Chunk复制
每个Chunk都被复制到不同机架上的不同的Chunk服务器上。当有Chunk服务器离线了,或者通过Chksum校验发现了已经损坏的数据,Master节点通过克隆已有的副本保证每个 Chunk都被完整复制。
5.1.3 Master服务器的复制
为了保证Master服务器的可靠性,Master服务器的状态也要复制。Master服务器所有的操作日志和checkpoint文件都被复 制到多台机器上。
如果Master 进程所在的机器或者磁盘失效了,处于GFS系统外部的监控进程会在其它的存有完整操作日志的机器上启动一个新的Master进程。
GFS中还有些“影子”Master服务器,这些“影子”服务器在“主”Master服务器宕机的时候提供文件系统的只读访问。
5.2 数据完整性
每个Chunk服务器都使用Checksum来检查保存的数据是否损坏。
对于读操作来说,在把数据返回给客户端或者其它的Chunk服务器之前,Chunk服务器会校验读取操作涉及的范围内的块的Checksum.
。如果发生某个块的Checksum不正确,Chunk服务器返回给请求者一个错误信息,并且通知 Master服务器这个错误。
5.3 诊断工具
详尽的、深入细节的诊断日志,在问题隔离、调试、以及性能分析等方面给我们带来无法估量的帮助,同时也只需要很小的开销。
Chunk服务器启动和关闭以及所有的RPC 的请求和回复。
日志的写入方式是顺序的、异步的。
6. 度量
6.1 小规模基准测试
6.1.1 读取
N个客户机从GFS文件系统同步读取数据。
6.1.2 写入
N个客户机同时向N个不同的文件中写入数据。
6.1.3 记录追加
6.2 实际应用中的集群
集群A通常被上百个工程师用于研究和开发。典型的任务是被 人工初始化后连续运行数个小时。它通常读取数MB到数TB的数据,之后进行转化或者分析,最后把结果写回到集群中。集群B主要用于处理当前的生产数据。集 群B的任务持续的时间更长,在很少人工干预的情况下,持续的生成和处理数TB的数据集。在这两个案例中,一个单独的”任务”都是指运行在多个机器上的多个 进程,它们同时读取和写入多个文件。
6.2.1 存储
两个集群都由上百台Chunk服务器组成,支持数TB的硬盘空间;
6.2.2 元数据
Chunk服务器总共保存了十几GB的元数据,大多数是来自用户数据的、64KB大小的块的Checksum。
在Master服务器上保存的元数据就小的多了,大约只有数十MB,
6.2.3 读写速率
6.2.4 Master服务器的负载
表3的数据显示了发送到Master服务器的操作请求大概是每秒钟200到500个。Master服务器可以轻松的应付这个请求速度,所以Master服务器的处理能力不是系统的瓶颈。
6.2.5 恢复时间
6.3 工作负荷分析(Workload Breakdown)
6.3.1 方法论和注意事项
本章节列出的这些结果数据只包括客户机发起的原始请求。我们从GFS服务器记录的真实的RPC请求日志中推导重建出关于IO操作的统计信息。
6.3.2 Chunk服务器工作负荷
6.3.3 记录追加 vs. 写操作
6.3.4 Master的工作负荷
7. 经验
建造和部署GFS的过程中,我们经历了各种各样的问题,有些是操作上的,有些是技术上的。
我们最大的问题是磁盘以及和Linux相关的问题。
8. 相关工作
GFS提供了一个与位置无关的名字空间,这使得数据可以为了负载均衡或者灾难冗余等目的在 不同位置透明的迁移。
由于磁盘相对来说比较便宜,并且复制的方式比RAID方法简单的多,GFS目前只使用复制的方式来进行冗余。
GFS并没有在文件系统层面提供任何 Cache机制。
我们选择了中心服务器的方法,目的是为了简化设计,增 加可靠性,能够灵活扩展。
而GFS使用的是普通计算机作为Chunk服务器。
9. 结束语
Google文件系统展示了一个使用普通硬件支持大规模数据处理的系统的特质。
首先,我们根据我们当前的和可预期的将来的应用规模和技术环境来评估传统的文件系统的特性。
我们认为组件失效是常态而不是异常,针对采用追加 方式(有可能是并发追加)写入、然后再读取(通常序列化读取)的大文件进行优化。
我们系统通过持续监控,复制关键数据,快速和自动恢复提供灾难冗余。
我们的设计保证了在有大量的并发读写操作时能够提供很高的合计吞吐量。
我们通过分离控制流和数据流来实现这个目标,控制流在Master服务器处理,而数据流在Chunk服务器和客户端处理。