原文链接:http://nil.csail.mit.edu/6.824/2020/papers/gfs.pdf
目录
相关背景介绍
GFS是google基于自身业务场景涉及的全局文件系统,与Map Reduce结合很好的满足了需求。因为这个系统主要用于处理特定任务,所以放宽了对于一致性的要求,会让刚读论文的同学很费解。因为很多时候同一个文件的多个replica在这里其实内容是不一定完全一致的,所以基于GFS的任务通常要能基于序列号执行自动检测和修复,又或者基于GFS的任务需要对于结果偏差有更强的包容性,整体而言比起现在使用的hdfs有更苛刻的设计要求。
整篇论文读下来,可以充分体会到,GFS本质是取舍的艺术。为了满足特定的需求,在很多方面都进行了取舍,例如chunk size,一致性等。
框架介绍
设计前提
1、因为GFS基于大量商业化廉价机器,因此因为各种因素导致的失败是常态而非异常。
2、存储管理的文件比较大,GB级属于常态,甚至可能出现TB级。
3、考虑到实际业务场景,与日常生活不同,通常文件修改都是直接在最后添加新的内容而非直接跳到指定地点执行写任务。
4、因为执行任务的特性,对于充分利用高带宽的需求要远大于低延迟的需求。
动作接口
GFS主要支持create,delete,open,close,read和write操作。
另外,为了加强容错性,GFS提供了snapshot操作。为了提升写效率,GFS提供了record append操作。
结构
GFS集群包括一个master和多个chunkservers,同时在集群外会有很多clients向集群发出请求想要读取文件内容。
Files被划分为固定大小的chunks(通常一个大文件被分为若干个64M的chunk)。每个chunk被Master分发决定的chunk handle唯一标识。每个chunk都会进行复制,通常replica数量为3.
Master本身不存储任何文件内容,其只负责存储关键信息对client请求进行调度通知。其保存了整个文件系统的metadata(元数据)。元数据包括了namespace,access control infromation,file和chunks的映射关系,chunk lease management,garbage collection等信息。Master定期与chunkserver通过HeartBeat Message进行通信,来更新保存的状态信息。
原文关于机制的描述
Master作用介绍
clients并不从master读取数据类型。其通过Master获取需要的chunk,进一步知道可以从哪些chunkserver里获得。之后直接联系chunkserver获得信息。另外client会把这些信息进行缓存,以减少与master的沟通。
ChunkSize设置问题
优点:
1、把ChunkSize设置的大一些,可以减少Client与Master的交互次数。
2、因为Chunk较大,大部分操作可能都会基于一个chunk处理,进而可以建立TCP长连接来实现稳定交互。
3、MetaData需要储存很多关于chunk的信息,增大chunk的大小可以降低chunk的数量,进而使得MetaData可以储存在Master的内存里。
缺点:
1、文件过大包含的内容变多,可能会有更多的client想要同时访问这个文件,使其成为hot spot,导致很多传输问题。
MetaData介绍
Master主要在内存中储存以下三种MetaData
1、file和chunk的namespace
2、file和chunks的映射关系(一个file可能对应多个chunk)
3、chunk的replicas的location
其中前两者还通过operation log保存在了master本身的硬盘并复制到其他机器上。
最后一个则没有进行永久化保存,而是在每次master重新启动或是有新的chunkserver添加到集群里时进行状态更新。
事实上,在启动时通过访问获取chunk location并在之后周期性更新是个很简单很好的方法。毕竟从工程设计上看,chunkserver本身负责其自身一系列的状态调整,例如失败、退出集群、重启、改名等操作。让master持久化保持chunk的状态并不是个很好的注意。
这个设计的考虑可见:https://www.cnblogs.com/dodoJavaLearner/p/5388521.html
Operation Log和CheckPoint
CheckPoint:采用写时复制的方法,初始单纯创建个指向对应chunk的指针。发生修改后创建chunk的副本更改指向的对象。其组织架构类似于B树。当Operation Log超过一定大小时便会创建checkPoint保存状态类信心并清空Operation Log。
Operation Log:包含了重要的MetaData变化的记录。
最后Master恢复时只需要checkpoint+该checkpoint对应时间之后的日志即可实现快速恢复。(恢复机制与Redis相似)
一致性模型
GFS采用了宽松一致性模型,很多时候会导致问题
consistent:当所有client不管从哪个replica读取都会读到相同的额内容时称为consistent
define:能在返回的地方读取自己刚刚写的内容
解读文章;https://blog.csdn.net/qiaojialin/article/details/71574203
系统交互
本部分将介绍client,master,chunkserver如何彼此交互来实现数据修改、record append以及snapshot
Lease and Mutation Order
每一个记录修改都要保证全部replica都进行了更新。
Primary:由Master给予lease的replica,将其视作primary。由其决定并发动作的执行顺序。
lease:lease机制用来减少master的管理复杂度,解耦合。一个lease有初始timeout60s,不过只要这个replica仍在执行mutation,他就可以实现lease的无限制延时。
Master偶尔可能会想要更改primary,即使其与replica失联,也可在默认的lease时间过去后进行更改。
执行机制:
DataFlow:为了充分利用带宽,加快传递速度,每个机器会自动像周边暂时还没收到信息的机器传递数据,进行自扩散,而非由一个机器进行统一的分发。(在Google的应用场景下,可以通过特定设计的ip来判断机器间的距离
Record Append
通常关于这类操作需要加锁
在GFS因为replica files大小统一,所以可以由primary进行统一调度。由primary决定顺序后进行写入,随后把顺序告知其他replica,让他们跟着实现。
snapshot采用写时复制的方法高效实现保存功能。先创建指向同一文件的指针,随后当文件进行写操作时再创建保存的副本。
Master Operation
Replica的创建以及放置要考虑三个因素
1、尽可能将replcia放在磁盘利用率低的机器上
2、尽可能不要在同一chunkserver上短时间创建多个replica,将创建内容打散。创建本身很简单,不过还要考虑后续沉重的写任务。
3、尽可能将replica跨rack(机架)保存,以防止相近位置机器同时出现问题崩溃,增加容错性。
Stale Replica Detection
每一个Chunk,master都会保存一个chunk version number来判断chunk的时效性
当master给chunk提供了一个新的lease时,master会增加chunk version number并告知给相关的replica。Master和replica都会记住这个replica。
如果此时一个replica因为某些原因失联,那么他的chunk version number就不会发生变化。之后当该chunkserver重启时master便会发现对应异常情况,重新创建新的replica等。
Stale Replica会被Garbage Collection定时进行处理
ChunkServer还需要通过CheckSum机制定时检测数据完整性并进行相应处理
以下内容来自知乎文章
容错与诊断
1. GFS中为提高可用性采取的措施:
- 快恢复:当有cs failed后,几秒内就保证其马上重启;
- chunk的replica也提高了可用性;
- 有一个monitoring会监视master的情况,如果master宕机会启动备份的master机器,该机器上有master备份的operation log、checkpoint;另外,还有”影子“master可以辅助提供读访问。
2. GFS中为保证数据完整性的措施:
1. 每个CS针对自己的每个chunk有对应的checksum,用于检查自己本地的每个chunk的数据是否发生错误;
2. CS读取数据的时候,若CS发现数据错误,那么会 a). 向master报告,请求master克隆一份正确的数据过来,b). 向client报告,请求client重新到其他有该数据正确的副本结点上去读取;
3. CS在空闲的时间会对不活跃的chunk进行数据完整性检查,防止这些数据一直没被读取而发现不了其中的错误。
问题与思考
- master中为什么使用log的方式,master崩溃后,log和checkpoint如何起到恢复作用?
失败重启后可以读取checkpoint,恢复内存中的元数据,然后读取该ckpt时间点后的log记录进行补充修正。使用log是因为追加的方式对磁盘很友好,如果使用数据库,那么b-tree会随机访问磁盘,不友好。 - master如何选择primary / 为什么需要version_number?
对于每个chunk handle,master在内存中有它的最新version_number,因此通过定期和CS交流后知道最新的chunk在哪个CS上,选择它为primary;因此,version_number可以帮助识别最新的replica数据;此外,有可能master会看到CS有更大的version_number,这可能是因为可能发完租约和最新的version_number后,master宕机了,没有更新本地的versionnumber,这种情况下,master会采用更大的version_number。 - 为什么需要lease?
如果没有lease,那么加入master先指定一个CS为primary,但是它宕机或者网络延迟了,然后master重新指定了一个CS,当前一个CS恢复后,以为自己还是primary,这样就有两个primary,会指定不同的次序进行写,那么就违反了一致性。有lease,那么在第一个CS的lease无效前,不会分配第二个lease。 - GFS不足的地方:
- 单一master是性能和可靠性的瓶颈;master的内存可能不够,client太多时CPU不够;master宕机后可能需要人为参与修改master的IP;
- CS处理小文件的随机访问效率不高;
- 一致性可能太放松了,有些场景的不适合。