MIT6.824
  • 简介
  • Lecture 01 - Introduction
    • 1.1 分布式系统的驱动力和挑战(Drivens and Challenges)
    • 1.2 课程结构(Course Structure)
    • 1.3 分布式系统的抽象和实现工具(Abstraction and Implementation)
    • 1.4 可扩展性(Scalability)
    • 1.5 可用性(Availability)
    • 1.6 一致性(Consistency)
    • 1.7 MapReduce基本工作方式
    • 1.8 Map函数和Reduce函数
  • Lecture 03 - GFS
    • 3.1分布式存储系统的难点(Why Hard)
    • 3.2 错误的设计(Bad Design)
    • 3.3 GFS的设计目标
    • 3.4 GFS Master 节点
    • 3.5 GFS读文件(Read File)
    • 3.6 GFS写文件(Write File)(1)
    • 3.7 GFS写文件(Write File)(2)
    • 3.8 GFS的一致性
  • Lecture 04 - VMware FT
    • 4.1 复制(Replication)
    • 4.2 状态转移和复制状态机(State Transfer and Replicated State Machine)
    • 4.3 VMware FT 工作原理
    • 4.4 非确定性事件(Non-Deterministic Events)
    • 4.5 输出控制(Output Rule)
    • 4.6 重复输出(Duplicated Output)
    • 4.7 Test-and-Set 服务
  • Lecture 06 - Raft1
    • 6.1 脑裂(Split Brain)
    • 6.2 过半票决(Majority Vote)
    • 6.3 Raft 初探
    • 6.4 Log 同步时序
    • 6.5 日志(Raft Log)
    • 6.6 应用层接口
    • 6.7 Leader选举(Leader Election)
    • 6.8 选举定时器(Election Timer)
    • 6.9 可能的异常情况
  • Lecture 07 - Raft2
    • 7.1 日志恢复(Log Backup)
    • 7.2 选举约束(Election Restriction)
    • 7.3 快速恢复(Fast Backup)
    • 7.4 持久化(Persistence)
    • 7.5 日志快照(Log Snapshot)
    • 7.6 线性一致(Linearizability)
  • Lecture 08 - Zookeeper
    • 8.1 线性一致(Linearizability)(1)
    • 8.2 线性一致(Linearizability)(2)
    • 8.3 线性一致(Linearizability)(3)
    • 8.4 Zookeeper
    • 8.5 一致保证(Consistency Guarantees)
    • 8.6 同步操作(sync)
    • 8.7 就绪文件(Ready file/znode)
  • Lecture 09 - More Replication, CRAQ
    • 9.1 Zookeeper API
    • 9.2 使用Zookeeper实现计数器
    • 9.3 使用Zookeeper实现非扩展锁
    • 9.4 使用Zookeeper实现可扩展锁
    • 9.5 链复制(Chain Replication)
    • 9.6 链复制的故障恢复(Fail Recover)
    • 9.7 链复制的配置管理器(Configuration Manager)
  • Lecture 10 - Cloud Replicated DB, Aurora
    • 10.1 Aurora 背景历史
    • 10.2 故障可恢复事务(Crash Recoverable Transaction)
    • 10.3 关系型数据库(Amazon RDS)
    • 10.4 Aurora 初探
    • 10.5 Aurora存储服务器的容错目标(Fault-Tolerant Goals)
    • 10.6 Quorum 复制机制(Quorum Replication)
    • 10.7 Aurora读写存储服务器
    • 10.8 数据分片(Protection Group)
    • 10.9 只读数据库(Read-only Database)
  • Lecture 11 - Cache Consistency: Frangipani
    • 11.1 Frangipani 初探
    • 11.2 Frangipani的挑战(Challenges)
    • 11.3 Frangipani的锁服务(Lock Server)
    • 11.4 缓存一致性(Cache Coherence)
    • 11.5 原子性(Atomicity)
    • 11.6 Frangipani Log
    • 11.7 故障恢复(Crash Recovery)
    • 11.8 Frangipani总结
  • Lecture 12 - Distributed Transaction
    • 12.1 分布式事务初探(Distributed Transaction)
    • 12.2 并发控制(Concurrency Control)
    • 12.3 两阶段提交(Two-Phase Commit)
    • 12.4 故障恢复(Crash Recovery)
    • 12.5 总结
由 GitBook 提供支持
在本页

这有帮助吗?

  1. Lecture 03 - GFS

3.5 GFS读文件(Read File)

上一页3.4 GFS Master 节点下一页3.6 GFS写文件(Write File)(1)

最后更新于4年前

这有帮助吗?

有了之前的基础,我接下来会列出GFS读和写的步骤,最后,我会介绍出现故障之后,系统是如何保持正确的行为。

对于读请求来说,意味着应用程序或者GFS客户端有一个文件名和它想从文件的某个位置读取的偏移量(offset),应用程序会将这些信息发送给Master节点。Master节点会从自己的file表单中查询文件名,得到Chunk ID的数组。因为每个Chunk是64MB,所以偏移量除以64MB就可以从数组中得到对应的Chunk ID。之后Master再从Chunk表单中找到存有Chunk的服务器列表,并将列表返回给客户端。所以,第一步是客户端(或者应用程序)将文件名和偏移量发送给Master。第二步,Master节点将Chunk Handle(也就是ID,记为H)和服务器列表发送给客户端。

现在客户端可以从这些Chunk服务器中挑选一个来读取数据。GFS论文说,客户端会选择一个网络上最近的服务器(Google的数据中心中,IP地址是连续的,所以可以从IP地址的差异判断网络位置的远近),并将读请求发送到那个服务器。因为客户端每次可能只读取1MB或者64KB数据,所以,客户端可能会连续多次读取同一个Chunk的不同位置。所以,客户端会缓存Chunk和服务器的对应关系,这样,当再次读取相同Chunk数据时,就不用一次次的去向Master请求相同的信息。

接下来,客户端会与选出的Chunk服务器通信,将Chunk Handle和偏移量发送给那个Chunk服务器。Chunk服务器会在本地的硬盘上,将每个Chunk存储成独立的Linux文件,并通过普通的Linux文件系统管理。并且可以推测,Chunk文件会按照Handle(也就是ID)命名。所以,Chunk服务器需要做的就是根据文件名找到对应的Chunk文件,之后从文件中读取对应的数据段,并将数据返回给客户端。

学生提问:可以再讲一下第一步吗?

Robert教授:第一步是,应用程序想读取某个特定文件的某个特定的偏移位置上的某段特定长度的数据,比如说第1000到第2000个字节的数据。所以,应用程序将文件名,长度和起始位置发送给Master节点。Master节点会从其file表单中查询文件名并找到包含这个数据段的Chunk,这样可以吗?

学生提问:如果读取的数据超过了一个Chunk怎么办?

Robert教授:我不知道详细的细节。我的印象是,如果应用程序想要读取超过64MB的数据,或者就是2个字节,但是却跨越了Chunk的边界,应用程序会通过一个库来向GFS发送RPC,而这个库会注意到这次读请求会跨越Chunk边界,因此会将一个读请求拆分成两个读请求再发送到Master节点。所以,这里可能是向Master节点发送两次读请求,得到了两个结果,之后再向两个不同的Chunk服务器读取数据。

学生提问:如果客户端有偏移量信息,那可以直接算出来是第几个Chunk吧?

Robert教授:客户端可以算出来是哪个Chunk,但是客户端不知道Chunk在哪个服务器上。为了获取服务器信息,客户端需要与Master交互。我不能保证究竟是在哪里决定的要读取的是第几个Chunk。但是可以确定的是,Master节点找到了Chunk对应的ID,并确定了Chunk存储在哪个服务器上。

学生提问:能再介绍一下读数据跨越了Chunk边界的情况吗?

Robert教授:客户端本身依赖了一个GFS的库,这个库会注意到读请求跨越了Chunk的边界 ,并会将读请求拆分,之后再将它们合并起来。所以这个库会与Master节点交互,Master节点会告诉这个库说Chunk7在这个服务器,Chunk8在那个服务器。之后这个库会说,我需要Chunk7的最后两个字节,Chunk8的头两个字节。GFS库获取到这些数据之后,会将它们放在一个buffer中,再返回给调用库的应用程序。Master节点会告诉库有关Chunk的信息,而GFS库可以根据这个信息找到应用程序想要的数据。应用程序只需要确定文件名和数据在整个文件中的偏移量,GFS库和Master节点共同协商将这些信息转换成Chunk。

学生提问:从哪个Chunk服务器读取数据重要吗?

Robert教授:是也不是。概念上讲,它们都是副本。实际上,你可能已经注意到,或者我们之前也说过,不同Chunk服务器上的数据并不一定完全相同。应用程序应该要能够容忍这种情况。所以,实际上,如果从不同的Chunk服务器读取数据,可能会略微不同。GFS论文提到,客户端会尝试从同一个机架或者同一个交换机上的服务器读取数据。