欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

GFS文件系统的架构分析

程序员文章站 2022-07-12 11:15:07
...
    Google文件系统(Google File System,GFS)是构建在廉价的服务器之上的大型分布式系统。它认为组件失效(注:可理解为服务器故障)是常态事件,而不是意外事件,通过自身对可能失效组件的持续的监控、错误侦测、灾难冗余以及自动恢复的机制,保证系统的可靠性,也降低了系统的设计成本。
 
系统架构
GFS文件系统的架构分析
            
    
    博客分类: 云计算 大数据云计算GFS架构    

     一个GFS集群包含三个角色:一个单独的GFS Master总控制服务器多台GFS Chunkserver(数据块服务器,简称CS)和多个GFS Client客户端.GFS存储的文件都被分割成固定大小的Chunk Chunk服务器把Chunklinux文件的形式保存在本地硬盘上,并且根据指定的Chunk标识和字节范围来读写块数据。为了保证可靠性,Chunk在不同的机器中复制多份,缺省情况下,使用3个存储复制节点,不过用户可以为不同的文件命名空间设定不同的复制级别。
 
     Master中维护了系统的元数据(SQL中的说法是:数据的数据),这些元数据包括Chunk名字空间、访问控制信息、文件和Chunk的映射信息、以及当前Chunk的位置信息.。Master还管理着系统范围内的活动,比如, Chunk租用管理无用Chunk的回收、以及Chunk在Chunk服务器之间的迁移。 Master节点使用心跳信息周期地和每个Chunk服务器通讯,发送指令到各个Chunk服务器并接收Chunk服务器的状态信息。
 
    Client代码实现了GFS文件系统的API接口函数以及应用程序的访问接口。应用程序从Master获取元数据,根据元数据提供的信息与Chunk服务器直接进行交互。从架构图可以看出Client和Master之间的交互只有控制流(指令信息),没有数据流,因此降低了Master的负载 (因为控制流只需传送指令和状态,数据量小Client与Chunk 之间直接传输数据流,同时由于文件被分成多个chunk进行分布式存储,因此Client可以同时并行访问多个Chunk,从而让系统的I/O并行度提高。GFS不提供POSIX标准的API的功能,因此,其API调用不需要深入到Linux vnode级别。
 
    需要注意的是,GFS中的客户端不缓存文件数据,只缓存Master中获取的元数据。Chunk服务器也不需要缓存数据,Chunk以本地文件的方式保存, Linux操作系统的文件系统缓存会把经常访问的数据缓存在内存中。
 
一致性模型
 

    GFS主要是为了追加(Append)而不是改写(Overwrite)而设计的。一方面是因为是改写的需求比较少,或者可以通过追加来实现;另一方面是因为追加的一致性模型相比改写要更加简单有效。若出现某些副本追加成功而某些副本没有成功的情况,失败的副本可能会出现一些可识别的填充(padding)记录。GFS客户端追加失败将重试,只要返回用户追加成功,说明在所有副本中都至少追加成功了一次。当然,可能出现记录在某些chunk副本中被追加了多次,即重复记录;也可能出现一些可识别的填充记录,应用层需要能够处理这些问题。

    另外,由于GFS支持多个客户端并发追加,那么多个客户端之间的顺序是无法保证的,同一个客户端连续追加成功的多个记录也可能被打断,比如客户端先后追加成功记录R1和R2,由于追加R1和R2这两条记录的过程不是原子的,中途可能被其它客户端打断,那么GFS的chunk中记录的R1和R2可能不连续,中间夹杂着其它客户端追加的数据。

    GFS的这种一致性模型是追求性能导致的,这也增加了应用程序开发的难度。对于MapReduce应用,由于其批处理特性,可以先将数据追加到一个临时文件,在临时文件中维护索引记录每个追加成功的记录的偏移,等到文件关闭时一次性将临时文件改名为最终文件。

 

系统交互:

 

   租约(lease)和变更顺序
 
     变更是一个会改变Chunk内容或者元数据的操作,比如写入操作或者记录追加操作。变更操作会在Chunk的所有副本上执行。Master通过Lease赋予主Chunk对其他副本的变更权限,在Lease有效期内,对该chunk的写操作都有主Chunk负责,从而减少Master的负担。一般来说,Lease的有效期比较长,比如60秒,只要没有出现异常,主Chunk可以不断向Master请求延长Lease的有效期直到完成变更操作或整个chunk写满。Master节点和主Chunk失去联系,它仍然可以安全地在旧的租约到期后和另外一个Chunk副本签订新的租约,保证数据的有序变更。
 
   追加过程
   在下图是写入操作的控制流程。
GFS文件系统的架构分析
            
    
    博客分类: 云计算 大数据云计算GFS架构 

1. 客户机向Master节点询问哪一个Chunk服务器持有当前的租约,以及其它副本的位置。 如果没有一Chunk持有租约, Master节点就选择其中一个副本建立一个租约(这个步骤在图上没有显示)。

2. Master节点将主Chunk的标识符以及其它副本的位置返回给客户机。客户机缓存这些数据以便后续的操作。只有在主Chunk不可用,或者主Chunk回复信息表明它已不再持有租约的时候,客户机才需要重新跟Master节点联系。

3. 客户机可以以任意的顺序推送数据到所有的副本上。 Chunk服务器接收到数据并保存在它的内部LRU缓存中。通过分离数据流和控制流,GFS基于网络拓扑情况对数据流的网络传输负载进行规划,提高系统性能。
 
4. 当所有的副本都确认接收到了数据,客户机发送写请求到主Chunk服务器。Chunk接收到的所有写请求,这些请求可能来自不同的客户机,主Chunk将确定这些操作顺序并完成写操作。

5. Chunk把写请求传递到所有的二级副本。每个二级副本依照主Chunk分配的序列号以相同的顺序执行这些操作。
6. 所有的二级副本回复主Chunk,它们已经完成了操作。

7. 主Chunk服务器应答客户端,如果有副本发生错误,将出现Chunk写成功但是某些副本不成功的情况,客户端将重试。
 
    当然,实际的追加流程远远没有这么简单。追加的过程中可能出现主Chunk的Lease过期而失去chunk修改操作的授权,主Chunk或者副本机器出现故障,等等。这些追加流程的异常处理留作读者思考。


容错和诊断机制  
 
    在GSF中,组件失效被视为常态事件,组件的失效可能造成系统不可用,更糟糕的是,还可能产生不完整的数据。下面讨论CFS如何面对这些挑战,以及当组件失效不可避免的发生时,用GFS自带工具诊断系统故障。
 
 
    chunk复制
 
     每个Chunk都被复制到不同机架上的不同的Chunk服务器上。用户可以为文件命名空间的不同部分设定不同的复制级别,缺省是3

    Master服务器的复制 
 
    为了保证Master服务器的可靠性, Master服务器的状态也要复制。 Master服务器所有的操作日志和checkpoint文件都被复制到多台机器上。
GFS Master的修改操作总是先记录操作日志,然后再修改内存,当Master发生故障重启时,可以通过操作日志恢复内存数据结构;另外,为了减少Master宕机恢复时间,Master会定期将内存中的数据以checkpoint文件的形式转储到磁盘中(注:可能是其他机器的磁盘)。为了进一步提高Master的可靠性和可用性,GFS中还有影子”Master服务器(Shadow Master它们是影子,而不是镜像,所以它们的数据可能比”Master服务器更新要慢。影子”Master服务器为了保持自身状态是最新的,它会读取一份当前正在进行的操作的日志副本,并且依照和主Master服务器完全相同的顺序来更改内部的数据结构。影子”Master服务器也会定期和Chunk服务器握手来确定它们的状态。

诊断工具
    GFS服务器会产生大量的日志,记录了大量关键的事件(比如, Chunk服务器启动和关闭)以及所有的RPC的请求和回复。这些诊断日志可以随意删除,对系统的正确运行不造成任何影响。然而,只有在存储空间允许的情况下会尽量的保存这些日志。GFS的诊断工具通过匹配请求与
回应,以及收集不同机器上的RPC日志记录,重演所有的消息交互来诊断问题。RPC日志还用来跟踪负载测试和性能分析。


负载均衡 

        Master节点管理整个系统里所有Chunk副本,在制定Chunk副本的分布策略时需要考虑多种因素,如网络的拓扑,机架的分布,磁盘的利用率等等。

   Chunk的副本有三个用途: Chunk创建,重新复制和重新负载均衡。
   

    当Master创建了一个chunk,它会根据如下因素来选择chunk副本的初始位置:(1) 新副本所在的Chunk Server的磁盘利用率低于平均水平;(2) 限制每个Chunk Server”最近”创建的数量。(3)每个chunk的所有副本不能在同一个机架。第二点容易忽略但却很重要,因为创建完chunk以后通常需要马上写入数据,如果不限制”最近”创建的数量,当一台空的Chunk Server上线时,由于磁盘利用率低,可能导致大量的chunk瞬间迁移到这台机器从而将它压垮。

 

    当Chunk的有效副本数量少于用户指定的复制因数的时候, Master节点会尝试重新复制一个chunk副本。这可能是由几个原因引起的:一个Chunk服务器不可用了, Chunk服务器报告它所存储的一个副本损坏了, Chunk服务器的一个磁盘因为错误不可用了,或者Chunk副本的复制因数提高了。每一个chunk复制任务都有一个优先级,按照优先级从高到低在Master排队等待执行,例如GFS提高会阻塞客户机程序处理流程的Chunk的优先级。

    最后,Master会定期扫描当前副本的分布情况,如果发现磁盘使用量或者机器负载不均衡,将执行重新负载均衡操作。无论是chunk创建,chunk重新复制,还是重新平衡,它们选择chunk副本位置的策略都是相同的,并且需要限制重新复制和重新平衡任务的拷贝速度,否则可能影响系统正常的读写服务。

 
垃圾回收
 

    当文件被删除后,GFS不会马上回收其物理存储,而是立刻把删除操作以日志的方式记录下来。把文件名改为一个包含删除时间戳的、隐藏的名字。Master定时检查,如果发现文件删除超过一段时间(默认为3天,可配置),那么它会把文件从内存元数据中删除,回收物理存储资源。在文件被真正删除之前,它仍能够被Master以特殊的方式访问。为了减轻Master服务器的负担,回收文件物理资源的工作交由Chunk服务器完成:在Chunk 和Master的心跳消息中,Master会回复在Master元数据中已经不存在的chunk信息,Chunk服务器才会释放这些Chunk副本的资源。

 

    另外,Chunk副本可能会因为Chunk服务器失效期间丢失了对Chunk的修改操作而导致过期。系统对每个Chunk都维护了版本号,过期的Chunk可以通过版本号检测出来。Master仍然通过正常的垃圾回收机制来删除过期的副本。

 

 

快照

    快照(Snapshot)操作是对源文件/目录进行一个”快照”操作,生成该时刻源文件/目录的一个瞬间状态存放与目标文件/目录中。GFS中使用标准的copy-on-write机制生成快照,也就是说,”快照”只是增加GFS中chunk的引用计数,表示这个chunk被快照文件引用了,等到客户端修改这个chunk时,才需要在Chunk服务器中拷贝chunk的数据生成新的chunk,后续的修改操作落到新生成的chunk上。

    为了对某个文件做Snapshot,首先需要停止这个文件的写服务,接着增加这个文件的所有chunk的引用计数,以后修改这些chunk时会拷贝生成新的chunk。对某个文件执行Snapshot的大致步骤如下:

1, 通过Lease机制收回对文件每一个chunk写权限,停止对文件的写服务;

2, Master拷贝文件名等元数据生成一个新的Snapshot文件;

3, 对执行Snapshot的文件的所有chunk增加引用计数;

    例如,对文件foo执行快照操作生成foo_backup,foo在GFS中有三个chunk C1,C2和C3。Master首先需要收回C1,C2和C3的写Lease,从而保证文件foo处于一致的状态,接着Master复制foo文件的元数据生成foo_backup,foo_backup同样指向C1,C2和C3。快照前,C1,C2和C3只被一个文件foo引用,因此引用计数为1;执行快照操作后,这些chunk的引用计数增加为2。以后客户端再次往C3追加数据时,Master发现C3的引用计数大于1,通知C3所在的Chunk Server本次拷贝C3生成C3′,客户端的追加操作也相应地转向C3′。


ChunkServer

ChunkServer管理大小均为64MB的chunk,存储的时候需要保证chunk尽可能均匀地分布在不同的磁盘之中,可能考虑的因素包括磁盘空间,最近新建chunk数,等。另外,Linux文件系统删除64MB大文件消耗的时间太长,且没有必要,删除Chunk可以只将对应的chunk文件移动到每个磁盘中的回收站,以后新建chunk的时候可以重用。

 

 

小结:

 

 

    GFS采用中心服务器的模式,该模式的最大优点是便于管理,因为中心服务器可以获知所有子服务器的状态,因而可以很方便的得知各个子服务器的负载状况等。但是这一模式也有一个比较致命的缺点,那就是单点故障。当单点故障发生在中心服务器时,将导致整个系统的不可用。不过,按照上述描述,GFS的中心服务器只是逻辑上是一个,可以知道,其实GFS的Manster还是有后备机制—shadow Master的,Master通过后备机制来应对中心服务器故障并且缩短其灾后恢复时间。

 

 

参考文献:The Google File System