GFS文件系统的架构分析
GFS主要是为了追加(Append)而不是改写(Overwrite)而设计的。一方面是因为是改写的需求比较少,或者可以通过追加来实现;另一方面是因为追加的一致性模型相比改写要更加简单有效。若出现某些副本追加成功而某些副本没有成功的情况,失败的副本可能会出现一些可识别的填充(padding)记录。GFS客户端追加失败将重试,只要返回用户追加成功,说明在所有副本中都至少追加成功了一次。当然,可能出现记录在某些chunk副本中被追加了多次,即重复记录;也可能出现一些可识别的填充记录,应用层需要能够处理这些问题。
另外,由于GFS支持多个客户端并发追加,那么多个客户端之间的顺序是无法保证的,同一个客户端连续追加成功的多个记录也可能被打断,比如客户端先后追加成功记录R1和R2,由于追加R1和R2这两条记录的过程不是原子的,中途可能被其它客户端打断,那么GFS的chunk中记录的R1和R2可能不连续,中间夹杂着其它客户端追加的数据。
GFS的这种一致性模型是追求性能导致的,这也增加了应用程序开发的难度。对于MapReduce应用,由于其批处理特性,可以先将数据追加到一个临时文件,在临时文件中维护索引记录每个追加成功的记录的偏移,等到文件关闭时一次性将临时文件改名为最终文件。
系统交互:
2. Master节点将主Chunk的标识符以及其它副本的位置返回给客户机。客户机缓存这些数据以便后续的操作。只有在主Chunk不可用,或者主Chunk回复信息表明它已不再持有租约的时候,客户机才需要重新跟Master节点联系。
3. 客户机可以以任意的顺序推送数据到所有的副本上。 Chunk服务器接收到数据并保存在它的内部LRU缓存中。通过分离数据流和控制流,GFS基于网络拓扑情况对数据流的网络传输负载进行规划,提高系统性能。
5. 主Chunk把写请求传递到所有的二级副本。每个二级副本依照主Chunk分配的序列号以相同的顺序执行这些操作。
6. 所有的二级副本回复主Chunk,它们已经完成了操作。
容错和诊断机制
Master服务器的复制
回应,以及收集不同机器上的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通过后备机制来应对中心服务器故障并且缩短其灾后恢复时间。