原创分享 MIT 6.824 分布式系统课程第三课:GFS

ty4z2008-github · 2020年03月14日 · 最后由 astaxie 回复于 2020年03月14日 · 139 次阅读

笔记:GFS

视频:Lecture 3: GFS

论文地址:The Google File System

课程概要

主要讨论 Google 第一代文件系统 GFS。

正文

这篇论文的价值?

  • 分布式存储系统是分布式系统的关键

    接口和语义化应该如何定义、内部是如何工作的

  • GFS 涵盖的内容在 6.824 中有很多相关知识的涉及

    并行性能、容错、复制、一致性

  • 这篇论文属于分布式系统的标志性论文之一,从应用程序到网络。并且得到工业界的验证

构建分布式存储的难点在哪儿?

  • 高性能:跨服务器的数据文件分片获取
  • 多服务器:标志着更多的故障
  • 容错:多副本
  • 复制:潜在的不一致
  • 一致性:导致性能降低

我们究竟想要如何样的一致性?

  • 理想模型:所有的操作就像单机一样
  • 服务端使用磁盘存储
  • 服务端一次只执行一次客户端操作(即使并发)
  • 读始终是最新的写入结果(即使服务器重启或崩溃)

因此,假设有几个场景 c1 和 c2 是并发写。在写完成后,发起 C3 和 C4 读取。那么会得到什么结果?

答案:可能是 1 或者是 2,但是两个读都应该是相同的值返回(强一致性模型),但是单机无法做到好的容错。在现实分布式系统中肯定存在副本。

为了容错而产生的复制,让强一致性变得棘手。多副本同步写入,势必带来的是性能影响。性能/一致性之间需要取舍

一个简单的场景:两台副本服务器、S1 和 S2,客户端先发起并行写操作,然后立即读取。

GFS

论文概要

Big & Fast:Google 的很多服务都需要统一的存储系统,Mapreduce、爬虫、索引、日志存储、分析、YouTube(?)、相册等等

Global:跨多个数据中心访问,任何客户端可以读取任何数据中心的文件。

sharding:一个文件可能跨多个服务器/磁盘。并行性能和磁盘利用

automatic recovery:出现故障能自动恢复

一个数据中心一次部署

暂时只供内部使用

大文件顺序访问:读/追加。而 GFS 又不是 DB(事务)

在 2003 年,GFS 是凭借什么获得了 SOSP 最佳论文?

文中的分布式、分区、错误容忍已经在分布式领域出现很久并不是第一次,主要的原因是:大规模在工业界,真实的世界中应用。对弱一致性和单 master 的实践。

GFS 架构

客户端(library,RPC --- 这个被使用者隐藏了起来)

每个文件被切分到独立的 64MB 块中

chunk server:每个块都有三份副本,所有的文件都可以迁移到其他 chunk 服务器。支持并行读/写(MapReduce)

也可以存储大文件

分工独立:master 负责读写分发,chunkserver 负责具体数据

Master 的数据

内存(容量小,速度快):

  • file name table:文件名和 chunkserver 的映射 map (写磁盘 Non-Volatile)
  • chunk table: 文件版本(Non-Volatile)、chunkserver 列表(Non-Volatile)、租约时间(Volatile)、primary 信息,它负责写数据,然后派发副本(Volatile)

磁盘:log(日志,每次写操作)、checkpoint(快照恢复,当重启时能快速恢复到保存的最新状态)

客户端如何读取一个文件?

  1. 发送一个请求<filename,offset> 到 master
  2. master 根据 offset 查询 chunk server(无缓存时)
  3. Master 响应最新的 chunkserver table 给客户端
  4. 客户端缓存 chunk handle 和 chunkserver 服务器列表
  5. 客户端发送请求<chunk handle,offset>到最近的 chunkserver
  6. chunkserver 从磁盘读取文件并响应给客户端(客户端接收的是 buffer,library 会合并为真正文件)

master 如何知道 chunk 是在哪个 chunkserver? 每次写都会经过 master

客户端如果是追加一条记录需要经过哪些步骤?

  1. 客户端询问 master 最新的 chunk offset
  2. 如果 master 没有找到 primary chunk(租约过期)
    1. 当没有 chunkserver 可写,并且最新的版本号 丢失时直接返回错误
    2. 从其他的副本选举出新的 primary chunkserver,以及文件的最新版本
    3. 增加版本号,并写日志到磁盘
    4. 告诉 primary 和 secondary 最新的版本号是多少
    5. 副本写新的版本到磁盘,并且响应结果给新的 Primary
  3. Master 告诉 client 主副节点,client 会对响应结果缓存。只有当 Primary 访问不到时才重新请求
  4. Client 发送文件到所有的 chunkserver(存内存)
  5. Client 通知 Primary 进行 append
  6. Primary 检查当前租约是否过期,chunkserver 是否有足够的存储空间
  7. Primary 根据 offset 重新计算新的偏移位置
  8. Primary 写 chunk 文件 (64MB)
  9. Primary 通知 secondary 新的 offset,并且 append 文件到 chunk file
  10. Primary 等待所有的副本响应(包括错误的响应,譬如空间不足、超时等)
  11. Primary 通知客户端成功或者失败
  12. 客户端可以从第一步开始重试

GFS 是如何保证一致性的?

GFS 只 保证一次原子写入,数据已经在一个副本落盘。在经过一定时间后,所有的副本数据会一致。

假设出现网络分区,导致脑裂 (split brain,存在两个 primary)。出现这种情况,GFS 引入 60 秒的租约时间,出现 primary 不能连通,就必须等待超时(剩余的时间 client 可以通过 cache 的 primary 信息计算)。

当 Primary 响应客户端已经成功 append 记录,随后客户端立即进行读取,看到的应是最新的文件。(注意:不是所有的客户端都能看到最新的文件,GFS 是弱一致性。需要等待时间同步到其他节点,通过 “就近” 复制.)

GFS 如何容错?

错误情况:机器崩溃,崩溃后重启、崩溃后被其他机器替换、消息丢失、分区。

假设设计的 GFS 是强一致性,需要处理什么问题?

e.g 保证所有的客户端看到的文件内容相同

  1. Primary 应能识别重复写入的请求(保持幂等性),或者是客户端应该处理重复发送
  2. 所有的副本要不全部成功,要不全部失败。(必须全部副本写入才能响应成功)
  3. Primary 崩溃,有些操作可能会被丢失。新的 Primary 需要与副本通信找回记录
  4. 避免读取到旧的数据,所有的读必须去 Primary 获取最新的记录。或者是在租约期内的副本。

GFS 性能

  1. 读取吞吐量大(94MB/sec/16 台 chunkserver),平均每台 6MB/sec(机械磁盘顺序查找的速度是 30MB/sec、每个网卡大约 10MB/sec 的速度)交换机的连接接近饱和。因此每台机器的性能还是比较低,得益于可扩展性不错,在生产环境中单个 GFS 集群可以达到 500MB/sec。但当遇到大量文件写入时,也会因为网络瓶颈而导致受限。
  2. 对文件进行 append 追加时,其最大的限制是最后一块 chunk 的追加,因为主 Chunk 会检查这次记录追 加操作是否会使 Chunk 超过最大尺寸(64MB)。如果超过了最大尺寸,主 Chunk 首先将当前 Chunk 填充到最大尺寸,之后通知所有其他副本做同样的操作,然后通知 client 要求其对下一个 Chunk 重新进行记录追加操作。

值得思考的问题

  • 为了更好的支持小文件存储,需要些什么?
  • 如何支持上亿的文件?
  • 能否把 GFS 用作通用的文件存储系统?
  • 跨异地复制如何优雅?
  • 现在的部署是一个 GFS 部署一个数据中心,那么数据中心容灾如何考虑?
  • GFS 如何应对缓慢的 chunk 服务器?

关于 GFS 工程师采访反馈: GFS: Evolution on Fast-forward

  • 文件数量的增加是一个大问题
  • Master 的内存是有上限的
  • 文件数量增加,Master 的 GC 就会慢下来
  • master 所能承载的客户端连接有限
  • 应用程序需要按照 GFS 改造
  • master 的故障转移需要手动处理(10s)

在后面使用 BigTable 解决小文件存储,并且开发的第二代 GFS——Colossus 正是为了解决单点 master 问题

总结

GFS 的论文阐述了性能、错误容忍、一致性相关的设计和评价。GFS 是 MapReduce 中的基础设施。

亮点:

  • 集群式文件系统演变为基础设施
  • 存储与管理的分离标志(name 管理在 master,文件存储在 chunkserver)
  • 并行吞吐
  • 大文件分块存储减少开销
  • 主 chunk 顺序写设计
  • 利用租期来解决 “脑分裂” 问题

不足:

  • 单 master 的限制:内存和 CPU
  • 对小文件存储不够友好
  • master 的故障转移不够好
  • 弱一致性

参考文献

第二课:RPC 和多线程

博客地址

更多原创文章干货分享,请关注公众号
  • 加微信实战群请加微信(注明:实战群):gocnio

824 坚持的同学,赞

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册