简介

GFS 是Google提出的分布式文件系统,主要是针对面向数据密集型的应用程序,其中包括MapReduce,BigTable。Google开发的GFS主要是针对于google对于写文件多为一次写多次读,且经常是对文件追加记录特点开发的文件系统,因此它针对的业务场景有局限的,针对小文件和随机读写性能一般。

架构

GFS文件系统

single master:保存metadata,metadata主要包括
1文件到chunk的映射
filename->array of chunk handles

2各个chunk的位置信息 version-number,primay ,lease 租期
handle->list of chunkServers
versionNumber
primary
lease expriation

3 log,checkpoint ->disk

chunkserver:正如其名,主要保存各个具体的chunk

主要的交互过程、

GFS文件系统

读数据

  1. Client 向master发送要读写的filename,offset;来获知对应的chunk信息,

  2. master返回chunk所在的机器位置(所有副本,是一个chunkServer列表)
    Client 会cache这些信息

  3. 根据某个策略选择一个server发起请求

写数据

  1. 同读数据一样,首先向master发起请求获取chunk信息
  2. 此时返回的信息包括chunk所在的chunkServer,还有哪一个server作为primary,其他的是secondary
  3. 然后Client会向所有副本发送要写的数据,为了避免网络瓶颈,发送的法式为链式,即若服务器分别为S1,S2,S3
    Client会首先向最近的服务器发送数据假设为S1,S1收到数据后立马发送到距离S2最近的服务器假设为S3,以此类推。
    此时的数据并未写到文件里,而是写入LRU-Buffer
  4. 当所有副本Server全部收到数据后,Client向primary发送写请求。
    注意,因为是并发执行的,可能primay同时收到多个写请求,因此primary负责对于所有的写请求排序,即序列化,分配给每个请求一个序号,按照这个顺序写每个请求
  5. primary向所有repliea server转发这些请求,从而使得每一个server按照同样的顺序执行,从而确保一致性
  6. 当primary收到所有的从replica的reply表明他们已经完成了操作,primay向client发送reply

注意

如果数据发生跨块,则GFS会对这种请求拆分成两个请求,使得不跨块

GFS的lease机制

当Client需要修改master的元数据,由于master只有一个,所以不存在一致性问题。所有只需要对metadata加锁就可以了。
但是当发生写操作时,必须要有一个primary来确定一个顺序来保证副本的一致性,这里的实现就是,master对于所有的副本中确定一个primary,并对primary的身份赋予一个期限-60s,primary可以在过期之前续约。master也可以回收这个lease。这样很可以避免split-brain问题

split-brain问题

即系统中同时有两个primay。这种情况可能是在网络出现问题时发生。master通过阶段的与chunkServer发送心跳包来检测chunkserver是否异常,如果某时刻网络出现问题,使得这个心跳包master无法收到,而primay并没有宕掉,超时后,master认定primay不可达,则会重新指定一个primay,从而使分布式系统中同时有两个primary.而采用lease机制后则可以很容易解决这个问题,只需要使得master在lease到期后再指定新primay即可。

GFS中的一致性模型

GFS中为了高吞吐,采用的了relaxed consistency。即系统中存在不一致的状态,但是GFS会采用相应的机制应对。
GFS中定义了几个数据状态,这个简单解释一下。详细参考点这里

consisitent状态:所有的客户端无论从哪一个副本读到的数据都是一样的
defined状态:即一个修改操作生效后,client可以知道这个修改是谁修改的,及同时只有一个client修改同样的数据
对数据修改后,数据的状态如图所示
GFS文件系统
线性执行必定是defined的,这个defineed interspersed with in consisitent 状态发生在这种情况
假设首先client要先写A,成功了,client要写B,primay写成功,两个副本一个执行成功,另一个执行失败,则primay上报给client写B失败,client会继续尝试写B,这个时候另一个Client要求对同一chunk追加record,C,所有副本中都执行成功了,然后重试B成功,此时的副本状态为

GFS文件系统

即defined interspeersed with in consistent

解决方法

应用程序如何区分上述的情况,GFS填充和记录重复
GFS客户端有专门的库来解决这个问题。
对于空隙检测可以通过在合法的记录前面记录一个checksum表明这是一个合法记录。若checksum无效则说明是填充空隙
对于重复记录项,应用程序可以通过唯一的checksum来识别,若读到两个相同的checkSum说明是重复项
hecksum无效则说明是填充空隙
对于重复记录项,应用程序可以通过唯一的checksum来识别,若读到两个相同的checkSum说明是重复项

相关文章: