cd ..

GFS

Updated October 7, 2022 , by fzdwx | gfstransaction
  1. 为了性能(Performance), 所以将数据分割放到大量的服务器上,从而实现并行的读取数据,这就是分片(Sharding).
  2. 而成败上千的机器总会发生错误,所以有了容错(Fault Tolerance).
  3. 实现容错最简单的方式就是复制(Replication),其中一个发生故障了就切换另一个.
  4. 使用了复制,如果你不够小心,那么它们之间就可能会不一致.数据就有可能出现问题,所以就有了不一致的问题(Inconsistency).
  5. 如果为了实现一致性(Consistency),那么就需要多进行额外的交互来保证一致性,所以代价就是低性能(Low Perf) ,但这与我们开始的希望不符合.

So,强一致性代表着低性能.

设计目标

  1. 由于GFS是建立在大量的计算机上的,而这些计算机会不可避免的发生故障.所以必须要进行:检查,容错以及快速从故障恢复.
  2. 主要支持大文件(例如说好几个G的文件),同时也支持小文件但不做针对性的优化.
  3. 工作负载主要由两种类型的读取组成:大的流式读取小的随机读取 .对于性能有过特别考虑的应用通常会作批处理并且对他们读取的内容进行排序,这样可以使得他们的读取始终是单向顺序读取,而不需要往回读取数据.
    • 在大的流式读取中,单个操作通常要读取数百k,甚至1m或者更大的数据.对于同一个客户端来说,往往会发起连续的读取操作顺序读取一个文件.
    • 小的随机读取通常在某个任意的偏移位置读取几kb的数据.小规模的随机读取通常在文件的不同位置,读取几k数据.
  4. GFS中的文件通常上一旦完成写入就很少会再次修改,所以主要针对大的流式读取,同时夜支持任意位置的小规模写入操作.
  5. GFS对多个客户端并行添加同一个文件必须要有非常有效且明确语义的支持,即原子操作.通常会有多个客户端会并行的对同一个文件进行append.
  6. 高性能的稳定带宽的网络要比低延时更加重要.我们大多数的目标应用程序都非常重视高速批量处理数据 ,而很少有人对单个读写操作有严格的响应时间要求.

架构

  1. 单个master,多个chunk server(保存具体的文件),多个client.
  2. 每个文件被拆分为一定大小(64mb)的块(chunk),且每个chunk有一个唯一的64位的标志(chunk handle).
  3. 每个chunk都会在不同的chunk server上保存备份(默认是3个),用户可以指定不同的复制级别.
  4. master管理元数据(metadata),例如文件到chunk的映射关系,chunk的位置信息等.
  5. master管理chunk的分片,孤点chunk的垃圾回收机制,chunk server之间的镜像管理等
  6. 每个chunk server与master之间有心跳机制,并在检测的过程中年发出指令并收集状态.

GFS Master中的metadata

  1. filename -> chunk ids(chunk handles) NV
  2. chunk handle与chunk数据的对应关系
    • chunk保存在哪个服务器上(chunk server list)
    • chunk的version no NV
    • chunk的primary chunk server,因为写操作在在其上进行
    • primary chunk server的lease expiration

这两个data table都在master的内存中存放,为了容错(例如说重启后数据不丢失数据),它会在磁盘上存储log,读取的使用从内存里面读取,写的时候会写入内存以及磁盘. 每当有数据变更时,就会在磁盘上的日志进行追加,并且定期(日志增长超过某一个大小)创建checkpoint(类似快照,不用从头开始读取)

GFS Read Steps

  1. 首先读请求就表明client有filename以及想要读取的位置(offset),然后发送给master.
  2. master收到请求后就从filenames中获取对应的chunk handles.而每个chunk的大小上固定的,所以就得到的具体开始的chunk handle.
  3. 然后根据chunk handle找到对应存放数据的chunk server的列表返回给client.
  4. client可以选择一个server来进行读取(论文中说会选择一个最近的服务器,应为google里面ip是连续的,可以根据ip判断远近) ,应为客户端每次只读取1mb或者64kb的数据,所以它会缓存chunk与chunk server的关系,这样就不用每次都请求.
  5. chunk server收到请求后,根据chunk handle(推测chunk是安装chunk handle进行命名的)找到对应的chunk以及offset对应的数据给客户端.

q1: 如果读取的数据跨越了一个chunk怎么办?

例如说client想要读取的数据超过了64mb,或者仅仅上是2个byte却跨越了chunk,client会在发送请求时注意到这次请求跨越了边界, 所以会将一个请求拆分为2个请求发送到master,所以这里可能上向master发送两次读请求,之后在向不同的chunk server读取数据.

多个副本之间变更顺序的一致性

针对一个chunk

  1. master授权给某个持有这个chunk的server一个租约期限(60s),称为primary.
  2. primary对所有的更改操作进行排序(serial order),然后其他的secondary根据这个顺序进行变更.
  3. 只要这个chunk正在变更,那么primary就可以向master申请延长租约.

GFS Write Steps

  1. client向master发送请求获取chunk server list(primary,secondaries), 如果没有primary,master就会选择一个secondary成为primary.
  2. client获取到chunk server list后会缓存下来,只有当primary 没有响应或租约过期后才会再次请求.
  3. client将数据推送到所有replicas,客户端不保证推送的顺序,每个chunk server会将数据保存在内部的lur cache中,直到数据被使用或过期.
  4. 当所有replicas都收到了数据,client将会发送一个写请求到primary,它标识了之前推送到每个副本的数据. primary将这些写入组织成一定的顺序应用到自己本地.
  5. primary然后将这个应用顺序转发给各个secondary.
  6. secondaries应用这个顺序完成修改并答复primary.
  7. primary答复client,如果出现了任意错误也会答复给client.在出现错误的情况下,write request也可能在primary以及secondary中成功 (如果primary直接就失败了,那么它将不会转发serial order给secondaries),client将认为这次请求是失败的,它会通过重试来处理( 3-7尝试几次重新写入)

GFS Atomic Record Appends

:::tip 对同一片区域个并发写入是不可序列化的 这片区域可能最终包含多个客户端的数据片段. :::

一个原子的append操作.recored append至少会在给定的offset(GFS自己选择的,因为这里可能会失败,可能有一些chunk server上有这个数据) 上追加到文件上一次,并将该offset返回给client.它类似O_APPEND保证原子性. recored append遵守 GFS Write Steps 流程,但是有一些特别的地方:

  1. client推送所有数据后,primary会检查append到该chunk后是否超过了单个chunk的大小.
  2. 如果超过了,则在当前chunk填充到最大offset时(secondary也要保存),回复client,指出该操作应该在下一个chunk上重试( record的大小需要控制在单个chunk最大值的四分之一,以保证碎片在可接收的水平).
  3. 如果没有超过最大大小,则按照正常的情况进行保存.

过期副本检测

如果chunk server发生故障而宕机或者丢失了某些更新请求,那么它就有可能过期了.对于每个chunk,master都维护了一个version no来标识最新和过期的副本.

当master为一个chunk的primary server授权或续期时就会增加version no并通知所有replicas进行更新.

在数据一致的情况下,master和所有replicas的version no是一致的(在client发送写请求之前可以保证).

当chunk server重启或上报version no时,master会检查它时否包含过期的副本,如果发现master发现version no大于它的记录,master会采用更高的version no进行更新.

master通过周期性的垃圾回收来删除过期的副本,在删除前,它会确认在它所有client的chunk信息请求的应答中没有包含这个过期的副本.

client在从master获取chunk server列表时会附带获取version no,所以它可以进行比对,选择最新的副本进行操作.

总结

这并不是一个合格的多副本,多活,高可用,故障自修复的分布式系统.

  1. gfs paper 原文
  2. gfs paper 中文翻译
  3. gfs 视频
  4. gfs 视频翻译
  5. Bad Replication Design