GFS论文读后感
该论文是Google的三架马车之一,是实现了一个面向大规模密集型应用,可伸缩的的分布式文件系统。分布式存储的开篇之作,论文中主要阐述了该系统接口的扩展,如何设计,最后又讲了性能测试以及生产环境下性能数据。
读后感不一定按论文框架描述,主要还是自己对系统的理解与总结
0 前言
论文在简介中谈到了系统设计的初始思路,要考虑的因素
- 组件(程序,系统,机器)故障属于常态事件,而不是意外事件
- 需要存储的文件非常巨大,通常是TB
- 绝大多数文件的修改采用在文件尾部追加数据,而不是覆盖原有数据的方式(顺序读多,而非随机读)
- 通过应用程序和文件系统的API协同设计提高了整个系统的灵活性
首先,在分布式存储中经常出现的话题有,并行性能,容错,复制,一致性。GFS在解决这些问题用到了比较直观的方式,下面会谈到。
在开始之前,我看到网上有篇文章写得很好,脉络清晰并且作者的思想也很make sense
,我这里就对其中一些我不太明白的点进行总结,具体可以看这篇Google File System-GFS 论文阅读
1 设计概述
典型得Master + Worker
结构,一个 Master 来管理任务、分配任务,而 Worker 是真正干活的节点。
分块存储
分块存储可以理解为原来一个工人 1 小时能制作 1 个玩具,现在我请十个工人,每个人做玩具的一个组件,最后拼接,现在 1 小时就能够做不止 10 个玩具。
这就是为什么分布式在各个领域应用得原因:并行操作
在GFS中,以 64 MB 为固定的 Chunk Size 大小,这远远大于典型的单机文件系统 chunk 的大小。(也就是单位读取数据大小)
优点在于:
- 减少了 Client 与 Master 服务器交互的次数
- 减少了 GFS Client 与 GFS chunkserver 进行交互的数据开销
- 减少了存储在主服务器上的元数据的大小
缺点在于:
- 小数据量(比如仅仅占据一个 chunk 的文件,文件至少占据一个 chunk)的文件很多时,当很多 GFS Client 同时将 record 存储到该文件时就会造成局部的 hot spots 热点。
单Master节点的设计
Master
周期性通过 HeartBeat 机制和每一个 chunkserver 进行通信,进行指令的发送以及状态信息的接收
主要负责:
- chunk租赁管理
- 孤立块的收集
chunckserver
之间chunk
迁移- 追加记录
- 对于 metadata 的维护以及为索要 metadata 数据的 GFS 客户端做出正确的响应;
在参考博文中叙述了架构运行的一个大致流程,其中,说了Master
节点中含有两个Table
,统称为metadata
Table 1
存储了
filename
以及其对应的chunk handler
Table 2
存储了
chunk hanler
以及其对应的chunkserver
对于Table1使用哈希表来存储,Table2使用B+树来存储
持久化机制
由于metadata
存储于内存中,但是由于内存是易失性存储体,因此还需要持久化操作
- 客户端向 Master 节点请求的 metadata 数据直接存储于 Master 的内存中,避免每次请求都需要进行磁盘 I/O;
- Master 节点使用日志 + checkpoint 的方式来确保数据的持久化;
- Master 节点内存中的 Table1 与 Table2 中的 nv 数据会定期存储到 Master 的磁盘上(包括 shadow Master 节点);
Metadata-元数据
Master
中有三类重要的metadata
数据:
- File 和 chunk 的 namespace(命名空间)
- file 到 chunk 的映射 Map
- 每一个 chunk replica 的存储位置
前两个就是前面说的两个Table,最后一个是通过启动时以及 chunkserver 加入集群时发起 chunkserver 的每个 chunk 数据块位置的询问,不会持久化到硬盘。
因为这样意义不大,chunkserver
对它自己的磁盘上有什么块或没有什么块有最终决定权。在 Master 服务器上维护这个信息的一致视图是没有意义的,因为 chunkserver 上的错误可能会导致块自动消失(例如,磁盘可能坏了并被禁用),或者运维为 chunkserver 重命名。
还有一个Operation Log 包含关键 metadata 数据更改的历史记录
一致性模型
GFS并不是强一致性的,他实现的是一个最终一致性的系统
上图是指修改之后的文件区域状态,这取决于修改类型,修改成功与否,是否存在并发
具体文件区域状态意思可以看参考博客
2 系统内部交互
租赁和修改顺序
详细流程解释这里也不说了。。
值得一提的是,数据流是通过线性进行传递的,也就是Client 负责给 primary 传输写入的数据,而 primary 负责给下一个 replica 传输数据,而下一个 replica 又负责给下下一个 replica 传输数据。如此,能充分利用每台机器的网络带宽,避免网络瓶颈和高延迟链接,并最小化通过所有数据的延迟。
原子的记录追加
普通写一般会指定一个offset写入,在并发的情况下,可能出现多个客户端数据交叉写入的情况。原子追加写入则只指定data,不指定offset,offset由GFS决定。
……
后续是主节点的操作以及容错与诊断,在参考博文中已经表达很详尽,我也不是很想去写了。其实如果真要完整写完可能字数就得达上万,虽然GFS的设计简单且容易理解,但作为十几年前的分布式系统著作,其蕴含的细节与内容是十分多的,阅读论文只是为了让我对分布式存储有一个大体的认识,而如果为了完成博文而阅读,就有点得不偿失了,所以,即然别人的博文写的更好,我也就不想去写太多了(为自己懒惰找借口)
3 收获
- GFS是一个单体
Master
,多个ChunnkServer
的模型 - 系统采用大文件的分块存储思想
- Master中包含了许多有用的
metadata
- GFS实现的并非是强一致性
- 尽量减少
Master
节点在所有操作的参与 - ……
优秀的设计通常是简单的。