分布式文件系统研究12:Google File System (2)
时间:2007-04-16 来源:leejianzhou
Google File System
2、系统交互
(1)租约(lease)和修改顺序
GoogleFS上的文件数据都维持了多个备份,一旦需要修改,必须对这多个备份都进行修改。GoogleFS使用租约来实现不同副本之间的数据一致性。对于某一个chunk,Master首先选定一个包含该chunk的ChunkServer作为原始节点(primary),原始节点首先执行一系列操作,然后再把这些操作在所有的结点上重新执行一次,保证了所有数据副本之间的数据一致性。
(2)数据流
GoogleFS的目标是充分利用每个机器的网络带宽,避免网络瓶颈和延迟
为了有效的利用网络,GoogleFS将数据流和控制流分离。数据是以流水线的方式在选定的ChunkServer链上线性的传递的。每个机器的整个对外带宽都被用作传递数据。为避免瓶颈,每个机器在收到数据后,将它收到数据尽快传递给离它最近的机器。
(3)原子性的record Append
GoogleFS提供了一个原子性的添加操作:record append。在传统的写操作中,Client指定被写数据的偏移位置,向同一个区间的并发的写操作是不连续的:区间有可能包含来自多个Client的数据碎片。在record append中, Client只是指定数据。GoogleFS在其选定的偏移处将数据至少原子性的加入文件一次,并将偏移返回给Client。
在分布式的应用中,不同机器上的许多Client可能会同时向一个文件执行添加操作,添加操作被频繁使用。如果用传统的write操作,可能需要额外的、复杂的、开销较大的同步,例如通过分布式锁管理。在GoogleFS的实际应用中,这些文件通常以多个生产者/单个消费者队列的方式提供服务,或是包含从多个Client的归并结果。
Record append和前面讲的write操作的控制流差不多,只是在primary上多了一些逻辑判断。首先,Client将数据发送到文件最后一块的所有副本上。然后向primary发送请求。Primary检查添加操作是否会导致该块超过块大小限制(64M)。如果这样,它将该块扩充到最大规模,并告诉其它副本做同样的事,同时通知Client该操作需要在下一个块上重新尝试。如果记录满足块大小限制的要求,primary就会将数据添加到它的副本上,并告诉其它的副本在在同样的偏移处写数据,最后primary向Client报告写操作成功。如果在任何一个副本上record append操作失败,Client将重新尝试该操作。这时候,同一个块的副本可能包含不同的数据,因为有的可能复制了全部的数据,有的可能只复制了部分。GoogleFS不 能保证所有的副本每个字节都是一样的。它只保证每个数据作为一个原子单元被写过至少一次。这个是这样得出的:操作要是成功,数据必须在所有的副本上的同样 的偏移处被写过。进一步,从这以后,所有的副本至少和记录一样长,所以后续的记录将被指定到更高的偏移处或者一个不同的块上,即使另一个副本成了primary。根据一致性保证,成功的record append操作的区间是已定义的,而受到干扰的区间是不一致的。
(4)快照(snapshot)
快照操作几乎在瞬间构造一个文件和目录树的副本,同时将正在进行的其他修改操作对它的影响减至最小。
我们使用copy-on-write技术来实现snapshot。当Master收到一个snapshot请求时,它首先废除将要进行snapshot操作的文件块上的lease。这使得任何一个向这些块写数据的操作都必须和Master交互以找到拥有lease的副本。这就给Master一个创建这个块的副本的机会。
lease被撤销或终止后,Master在磁盘上登记执行的操作,然后复制源文件或目录树的metadata以对它的内存状态实施登记的操作。这个新创建的snapshot文件和源文件(其metadata)指向相同的块(chunk)。
Snapshot之后,客户第一次向chunk C写的时候,它发一个请求给Master以找到拥有lease的副本。Master注意到chunk C的引用记数比1大,它延迟对用户的响应,选择一个chunk handle C’,然后要求每一有chunk C的副本的ChunkServer创建一个块C’。每个ChunkServer在本地创建chunk C’避免了网络开销。从这以后和对别的块的操作没有什么区别。
3、MASTER操作
MASTER执行所有名字空间的操作,除此之外,他还在系统范围管理数据块的复制:决定数据块的放置方案;产生新数据块并将其备份;协同其他系统操作来确保数据备份的完整性,在所有的数据块服务器之间平衡负载并收回没有使用的存储空间。
3.1 名字空间管理和加锁
与传统文件系统不同的是,GoogleFS没有与每个目录相关的能列出其所有文件的数据结构,它也不支持别名(unix中的硬连接或符号连接),不管是对文件或是目录。GoogleFS的名字空间逻辑上是从文件元数据到路径名映射的一个查用表。
MASTER在执行某个操作前都要获得一系列锁,例如,它要对/d1/d2…/dn/leaf执行操作,则它必须获得/d1,/d1/d2,…, /d1/d2/…/dn的读锁,/d1/d2…/dn/leaf的读锁或写锁(其中leaf可以使文件也可以是目录)。MASTER操作的并行性和数据的一致性就是通过这些锁来实现的。
3.2 备份存储放置策略
一个GoogleFS集 群文件系统可能是多层分布的。一般情况下是成千上万个文件块服务器分布于不同的机架上,而这些文件块服务器又被分布于不同机架上的客户来访问。因此,不同 机架上的两台机器之间的通信可能通过一个或多个交换机。数据块冗余配置策略要达到连个目的:最大的数据可靠性和可用性,最大的网络带宽利用率。因此,如果 仅仅把数据的拷贝置于不同的机器上很难满足这两个要求,必须在不同的机架上进行数据备份。这样即使整个机架被毁或是掉线,也能确保数据的正常使用。这也使 数据传输,尤其是读数据,可以充分利用带宽,访问到多个机架,而写操作,则不得不涉及到更多的机架。
3.3 产生、重复制、重平衡数据块
当MASTER产生新的数据块时,如何放置新数据块,要考虑如下几个因素:(1)尽量放置在磁盘利用率低的数据块服务器上,这样,慢慢地各服务器的磁盘利用率就会达到平衡。(2)尽量控制在一个服务器上的“新创建”的次数。(3)由于上一小节讨论的原因,我们需要把数据块放置于不同的机架上。
MASTER在 可用的数据块备份低于用户设定的数目时需要进行重复制。这种情况源于多种原因:服务器不可用,数据被破坏,磁盘被破坏,或者备份数目被修改。每个被需要重 复制的数据块的优先级根据以下几项确定:第一是现在的数目距目标的距离,对于能阻塞用户程序的数据块,我们也提高它的优先级。最后,MASTER按照产生数据块的原则复制数据块,并把它们放到不同的机架内的服务器上。
MASTER周期性的平衡各服务器上的负载:它检查chunk分布和负载平衡,通过这种方式来填充一个新的服务器而不是把其他的内容统统放置到它上面带来大量的写数据。数据块放置的原则与上面讨论的相同,此外,MASTER还决定那些数据块要被移除,原则上他会清除那些空闲空间低于平均值的那些服务器。
3.4 垃圾收集
在一个文件被删除之后,GoogleFS并不立即收回磁盘空间,而是等到垃圾收集程序在文件和数据块级的检查中收回。
当一个文件被应用程序删除之后,MASTER会立即记录下这些变化,但文件所占用的资源却不会被立即收回,而是重新给文件命了一个隐藏的名字,并附上了删除的时间戳。在MASTER定期检查名字空间时,它删除超过三天(可以设定)的隐藏的文件。在此之前,可以以一个新的名字来读文件,还可以以前的名字恢复。当隐藏的文件在名字空间中被删除以后,它在内存中的元数据即被擦除,这就有效地切断了他和所有数据块的联系。
在一个相似的定期的名字空间检查中,MASTER确认孤儿数据块(不属于任何文件)并擦除他的元数据,在和MASTER的心跳信息交换中,每个服务器报告他所拥有的数据块,MASTER返回元数据不在内存的数据块,服务器即可以删除这些数据块。
3.5 过时数据的探测
在数据更新时如果服务器停机了,那么他所保存的数据备份就会过时。对每个数据块,MASTER设置了一个版本号来区别更新过的数据块和过时的数据块。
当MASTER授权一个新的lease时,他会增加数据块的版本号并会通知更新数据备份。MASTER和备份都会记录下当前的版本号,如果一个备份当时不可用,那么他的版本号不可能提高,当ChunkServer重新启动并向MASTER报告他的数据块集时,MASTER就会发现过时的数据。
MASTER在定期的垃圾收集程序中清除过时的备份,在此以前,出于效率考虑,在各客户端访问chunk,MASTER应答时,它会认为根本不存在过时的数据(也就是说,MASTER不知道数据过时了,而是照常应答,这样会导致错误)。为此,作为另一个安全措施,MASTER在给客户及关于数据块的应答或是另外一个读取数据的服务器数据是都会带上版本信息,在操作前客户机和服务器会验证版本信息以确保得到的是最新的数据。