您的位置:首页 > 编程语言 > Go语言

[MIT 6.824 Distributed System] Google File System

2016-06-30 08:43 381 查看

Google File System (GFS)

主题:性能、容错、一致性

参考论文:http://nil.csail.mit.edu/6.824/2016/papers/gfs.pdf

Google File System GFS
什么是一致性consistency

理想的一致性模型

造成不一致的根源

GFS 的目标

GFS中的文件有什么性质

主要的挑战

顶层设计

Master 如何做到容错

Chunk 容错

Chunks 的一致性

并发 写入追加见论文33

小结

什么是一致性(consistency)?

当data是多副本的并发读写的的时候,保持数据的一致性是非常重要的。

弱一致性:read() 可能返回过期的数据(stale data)——不一定是最新的数据。

强一致性:read() 返回最近一次 write() 的数据。

权衡:strong consistency is good for applications’ writers; but is bad for performence.

理想的一致性模型

多副本文件系统表现得就像无副本文件系统一样(表现得就像:多用户access 同一台机器上的单个磁盘)。

我们的目标就是要实现这种透明性。

造成不一致的根源

并发(concurrency)

错误(failure)

网络分割(network partition)

GFS 的目标?

创造一种基于集群的共享文件系统,存储超大规模数据集。(基于常用的Linux服务器集群,而不是大型机或超算)。

GFS中的文件有什么性质?

数据集很(multi TB)

系统中有不少大文件(几百M甚至几个GB)

append-only(many large, sequential writes that append to data files)

主要的挑战?

当集群规模很大时,机器崩溃(failures)变得十分频繁

做到高性能:大量的并发读写

如何提高网络利用率

顶层设计

为什么采用三个副本?

提高可用性(availability)

负载均衡(如果数据经常被读,多副本可以均衡负载)

为什么不用RAID磁盘阵列?

RAID并不是一般常用品。而且我们要使得机器具有容错性,而不仅仅是存储设备。

为什么 chunks 设计得这么大?

减少clients 与 master 的交互次数。

保持更长时间的TCP连接,减少网络开销。

减少master 存储元数据(metadata)的空间。

Master 如何做到容错?

单一Master (论文2.4)

client 总是要跟 master 联系,这种中心化管理可以避免很多问题。master 可以将 client 的操作 log 下来,有利于恢复。

持续性地(persistently) 存储有限的信息(论文2.6 metadata)

GFS的master 只存储最基本的文件和目录的元数据,可以有限做到分离。持续性地存储下面两类元数据:

the file and chunk namespace (目录)

file-to-chunk mapping(文件到块的映射)

对上面两类数据的修改操作打log (operation log)

log 要备份到多台远程机器上。

仅当 log 顺利记录到本地和远程磁盘上后,才会回复client。

限制 log 的大小

定期建立 checkpoint,在检查点之前的旧日志会全部被删除。日志尽可能小,可以加快崩溃后的恢复速度。

恢复

首先将所有操作跑一遍(从上次检查点开始),恢复目录和映射。(replay operation logs after checkpoint)

然后轮询chunkservers, 将chunk的位置信息恢复。

影子master (shadow master)(论文5.1.3)

master 除了有多个镜像外,还有影子。影子跟镜像方式不太一样,影子是紧跟主master的步伐,慢一点,所以不完全相同,没那么新鲜;而镜像之间应该是完全相同的。影子可以提供“只读”服务,为master分担一些工作量,只是data没那么新鲜罢了。

Chunk 容错

对chunk最多的操作是修改(mutation),那么如何避免在修改过程中的错误呢?

GFS中主要采用租约机制(lease,见论文3.1节):

首先client 会询问 master 哪个 chunk 握有当前租约(如果没有,就分配租约给其中一个副本),该chunk 就作为主chunk(primary)。

client 将数据 push 到所有的副本中。注意,push 的过程是按照网络拓扑传输的,而不是先传给primary再给secondary,这么做是为了以最快的速度将数据push到所有的副本中(最快速度拷贝)。

当所有replicas 都接收完数据,client 就会向 primary 发出写入请求。

primary 为所有修改操作分配连续的序号(因为修改操作可能来自多个clients,所以必须保证执行顺序)

primary 按照序号的顺序,对本地数据执行修改操作

primary 将请求转发给其他的 replicas

primary 收到所有 replicas 的回复后,才响应client,完成修改。

如果其中一个副本没有响应或修改失败,client 就会重试

除了上述的租约机制,master 还会执行re-replication 和 rebalance (见论文4.3节):

当某个chunk 副本的数目低于设定值(默认为3),master 就会尽快对该chunk 进行再备份(re-replication)。

master 还会根据 chunk 的访问情况对其副本进行负载均衡,这是为了使磁盘利用率更为平均,提升性能。

Chunks 的一致性

GFS 如何保证所有chunks都是一致的呢?(见论文2.7.1节,4.5节)

GFS 使用 chunk 版本号(chunk version number)来检测chunk 是否新鲜(stale)。

当master分配一个租约给某个chunk时,它会增加版本号并通知所有的副本。master 和 chunkservers 都持续性地存储这个版本号。那么 master 如何检测到 chunk 是不新鲜的呢?一旦chunkserver崩溃重启,它会向master 汇报它的chunks的版本号。如果master 发现其中某个chunk的版本号比自己存储的版本号小,那么这个chunk肯定是不新鲜了。

版本号还会发给client,使client也可以检测数据是否新鲜。

并发 写入/追加(见论文3.3)

在传统的“写入”中,通过偏移量offset 就可对数据进行随机读写。而在并发情况下,常常会有多个client并发地在不同机器[/b]上对同一个文件进行写入操作(例如,log 文件)。显然,传统的随机写入并不适合并发环境,因为要搞好竞争关系往往要引入复杂的机制,会严重降低分布式系统的读写性能。所以,在GFS中,采用追加的方式修改文件。

GFS提供一种称为记录追加(record append)的原子操作。此操作保证至少一次追加(at least once)。为什么是至少一次呢?且看记录是如何追加的:

追加也是一种修改,所以跟上述GFS的修改方式一样,必须要所有replicas都追加了,才算成功。只要有一个replica追加失败,client 就会重试。可见,虽然某些replicas已经成功追加,但client的重试使得他们只得再加一次。所以,某些记录可能会被追加多次,但至少有一次。

小结

GFS 中使用的重要容错技术:

日志和检查点(logging & checkpointing)

chunk 采用主/备份副本存储

GFS适合于什么?长处?

大规模连续地读写

追加(append)

大吞吐量(三个副本供同时读取,并且将clients的读取聚合起来,使得网络接近饱和状态)

数据容错性好(三个以上副本)

不足:

管理采用集中化模式(单master),master容错性能不够好。

小文件(master是瓶颈,若clients大量读取小文件,每次都要先请求master,那么master的工作量就会激增)

对于并发的文件更新还不够好(除了append)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  gfs 分布式 MIT