Google论文之Google File System笔记

宋鑫    2017-10-25

本文:Google论文之Google File System笔记,原创于:宋鑫的官方网站,转载请注明出处,谢谢。

1.介绍

GFS需要满足性能,可伸缩,可靠性和可用性。
并且将基础组件的故障看做是常态,因为集群机器太多,机器上的磁盘更多,所以单一磁盘损坏的事件很常见。
造成故障的原因有:应用程序bug,操作系统bug,人为误操作,磁盘,内存,连接器,网络故障,甚至有可能是机房断电。
因此需要对GFS进行持续性的监控,故障自探测,必须具备容错性,自恢复性,而且它们必须成为系统整体性的一部分。
在开发GFS时面对问题的特性有:大多数写文件操作都是追加,而不是重写。
通过应用和文件系统API的联合设计,大大降低了系统设计的复杂性,提高了灵活性。

2.设计概览

2.3架构

GFS集群是由一个master和多个chunkserver组成,并同时供多个客户端访问。
GFS-Architecture

master作用

在每个数据块生成的时候,master都会分配一个全局唯一不可变的64位ID,来进行标识。
数据块会生成多个副本,并被分配到chunkserver集群上。
副本因子默认值是3,当然用户可以对不同的文件区域设置不同的副本因子。

master负责维护所有文件系统的元数据信息,包括:
命名空间,访问控制信息,文件到数据块的映射信息,以及所有数据块的位置信息。
master也控制数据块的租约管理,无用数据块的垃圾回收,数据块在chunkserver之间的迁移。
master通过定时心跳和chunkserver通信,并向它发送执行指令,收集chunkserver的状态信息。

客户端作用

客户端实现了文件系统api,并替代应用与master,chunkservers通信。
客户端只向master请求元数据信息并缓存到本地,比如文件存在那个chunkserver上,
然后通过元数据信息向指定的chunkserver发送请求。
但是客户端和chunkserver都不缓存文件数据,而是通过linux的缓存区缓存经常被访问到的数据。

客户端怎么读数据

  1. 首先,客户端通过读取数据块大小,将应用指定的文件名和字节偏移量转化为文件块索引。
  2. 然后发送文件名和块索引给master,master响应并返回相应的数据块句柄和副本位置信息。
  3. 客户端将文件名和数据块索引作为key缓存起来,然后发送请求到最近的存有副本的chunkserver。

客户端的请求中包含数据块句柄和字节范围,之后就不用和master交互,直到租约过期或文件被重新打开。
租约过期之后,客户端就需要再次和master交互,进行续租,这就是租约机制。
客户端一个请求会同时询问多个数据块的信息,为了减少和master之间的网络请求交互。

2.5 数据块大小

默认为64M,惰性空间分配机制避免了磁盘空间的浪费。

大数据块的优点:

  1. 减少客户端和master之间的交互,因为相同块上的读写只需要初始化时的一次请求
  2. 客户端更倾向于在同一个块上进行更多的读写操作,大大减少了网络开销
  3. 减少了master需要存取的元数据信息,因此可以直接将元数据信息载入到内存中

大数据块的缺点

  1. 单个数据块所在的chunkserver很可能成为数据热点,造成网络拥堵。
    可以通过增加此数据块的副本因子数量解决。

2.6 元数据

master存取三类元数据:

  1. 文件和数据块的命名空间
  2. 文件到数据块的映射信息
  3. 数据块副本的位置信息。

命名空间和映射信息的改变会被持久化到操作日志上,并同步复制到多个远程机器。
master不持久化数据块的位置信息,master启动时会主动询问chunkserver上数据块的位置信息。

2.6.1 内存数据结构

元数据载入到内存中,便于master的全局定时扫描,垃圾回收,数据块复制,数据块迁移等。
64M块只需要64位的元数据信息,使用了前缀压缩机制。

2.6.2 数据块位置信息

master通过定时心跳和监控来更新chunkserver上的数据块信息。
主要是更新以下变更信息:chunkserver加入和离开集群,chunkserver重命名,宕机,重启等等 。

chunkserver对数据块的信息有最后的话语权,因为有可能是磁盘坏了,或者操作员对chunkserver进行了重命名。

2.6.3操作日志

操作日志中包含历史的重要元数据变化信息,它本身是一条时间逻辑线。
master只有在操作日志本地刷磁盘和同步到远程副本都成功后,才会响应给客户端,以达到一直性。
master通过重做操作日志进行恢复。为了减少启动时间,需要减小日志大小。
当操作日志增长超过一定阀值,会做一个checkpoint,将checkpoint之前的操作日志废弃。
checkpoint是一个压实的B-tree,会载入到内存中,并直接用于命名空间的查找,提高master的恢复速度和可用性。

2.7一致性模型

命名空间锁定机制保证了读写操作的原子性和正确性。master的操作日志定义了操作的全局顺序性。
写操作如果全部成功,就是明确区域,有部分失败的就是不明确区域,不明确区域会被垃圾回收。

对数据块进行的尾部添加操作是at least once语义。
对数据块的改变会以同样的顺序应用到所有的副本上。
使用块版本号来探测和区分陈腐的副本。陈腐副本的造成原因是:在做数据块更新时,chunkserver挂了,没执行更新。
这些陈腐副本会被垃圾回收,并且不会参与到响应客户端请求和后续的数据更新。
客户端的缓存有可能会读到陈腐副本的位置信息,但是缓存会在文件被重新打开后就会失效。
还有缓存有效期的窗口保证发生频率很小。而且有checksums机制,可以进行数据一致性验证。

3.系统交互

原则是:最小化master在所有交互操作中的介入。

3.1租约和变更顺序

变更一般是指 :改变文件内容或者数据块的元数据信息
使用租约机制来保持在所有副本上变更顺序的一致性。
master授予租约给一个副本,我们称它为主副本。
主副本为所有的变更选取一个串行序号,所有副本必须遵守。

主副本其实是一种代理机制,为了减少master的管理介入,租约失效后,由主副本续租。
当然master也可能在失效前撤回租约。
GFS-Interactive-Process

客户端,chunkserver,master的交互流程

  1. 客户端询问master,目前哪个chunkserver持有指定数据块的租约,以及其他副本的位置信息。
    如果一个chunkserver持有租约,那么master会生成一个租约并授予某个副本。
  2. master响应并返回主副本和其他副本的位置信息,客户端缓存起来。
    当主副本不可用,或主副本失去租约时,客户端会再次向master发送请求。
  3. 客户端将数据推送到所有的chunkserver。chunkserver接受并保存到自己内部的LRU缓冲区中,
    直到数据被使用或过期。这里通过将数据流从控制流中解耦出来,大大提高了性能。
  4. 当所有副本确认接收到数据,客户端向主副本发送写数据请求。
    主副本会分配连续的序号对应到所有的变更,然后将变更写入到本地数据块,并更新状态。
  5. 主副本转发写请求给其他副本,执行相同操作。
  6. 其他副本完成后,全部将结果返回给主副本。
  7. 主副本响应所有结果给客户端,任何副本发送的任何错误都会报告给客户端。
    客户端会对失败的chunkserver上的文件区域进行重试,通过步骤3和步骤7。

3.2 数据流

客户端不是同时向多个chunkserver发送数据,而是将所有变更集合起来,单一的向一个最近的chunkserver发送, 当这个chunkserver接收成功之后,它会进行转发,同样是发到最近的chunkserver。

3.4 快照

当需要对数据块进行快照时,master会撤回所有数据块相关的租约。
这是为了保证所有接下来的写操作都需要先与master确认租约持有人,而这时master就能先做数据块拷贝。 进行数据块拷贝时,master将操作变更先记录到持久化的操作日志中,然后应用到内存中的元数据信息。
简单点说就是先将原来的数据块拷贝,然后将租约给拷贝,然后在拷贝上写。

4.master操作

master的职责有:管理数据块副本,并分发到chunkserver,生成新的数据块,并复制等。
一个文件操作可能需要很多层级目录到内存元数据信息的映射,以及每个层级的锁。

4.4垃圾回收

当文件被应用删除时,master会马上记录这个删除操作到操作日志中。
而文件会被重命名为一个隐藏文件,但不是马上删除并对外宣布释放资源。
master后台程序定时扫描,如果发现超过了3天(或N天)的此类隐藏文件,会擦除掉内存中相应的元数据信息,
然后master通过心跳信息告知给所有的chunkserver,让chunkserver删除掉磁盘上对应的副本文件。

4.5陈腐副本的探测

master通过数据块的版本号信息来辨别陈腐副本;
每次当数据块进行新的续约,会将版本号加一并同步给其他的chunkserver上的数据块副本。

5.容错和诊断

通过2个策略来进行容错和诊断:1.快速恢复;2.多副本。


文章有用?分享给你的朋友们,让更多的人受益


更多精彩干货,尽请关注我的个人微信公众号
wechat