[MIT 6.824 Distributed System] Google File System

来源:互联网 发布:易赛充值软件官方网站 编辑:程序博客网 时间:2024/05/21 19:35

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)变得十分频繁
  • 做到高性能:大量的并发读写
  • 如何提高网络利用率

顶层设计

  1. 为什么采用三个副本?

    • 提高可用性(availability)
    • 负载均衡(如果数据经常被读,多副本可以均衡负载)
  2. 为什么不用RAID磁盘阵列?

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

  3. 为什么 chunks 设计得这么大?

    1. 减少clients 与 master 的交互次数。
    2. 保持更长时间的TCP连接,减少网络开销。
    3. 减少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并发地不同机器上对同一个文件进行写入操作(例如,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)
1 0