概述
本文是Lec3的先修内容,需要精读GFS论文。
简介
Google设计GFS的原因是旧的文件系统已经无法适配现有的集群环境,主要体现在以下几点。
- 集群中的节点发生故障成为一种常见现象,新系统必须具备持续监控、异常检测、容错和自动恢复的能力
- 文件变得十分庞大(TB),原有的基于小文件(KB)的I/O设计思路需要改变。
- 文件的追加写入操作次数远高于覆盖次数。
- 需要提升系统的易用性
设计概览
机遇和挑战
GFS面临的挑战主要有如下几点。
- 系统通常由许多廉价节点组成,因此经常发生故障
- 系统中存放大量的GB级别文件,需要对它们进行有效的管理
- 文件负载主要包括两种,streaming read和random read
- 文件负载还包括向文件追加写入大量内容
- 系统必须能够处理多个客户端并发追加写入同一文件的情况
- 高吞吐量低延迟更重要
接口API
GFS提供了可以了多个API接口,如create
, delete
, open
, close
, read
, write
, snapshot
, record append
。其中snapshot
可以快速的对文件进行拷贝,record append
支持多个客户端对同一个文件并发追加内容。
架构
一个GFS集群包括一个master,多个chunkservers和多个clients,clients可以访问到chunkservers,具体架构如下图所示。
GFS中,文件被分成固定大小的多个chunks,每个chunk由一个全局的64bit大小的不可更改的chunk handler唯一识别。在创建chunk时,master节点会为每个chunk分配chunk handler。Chunkserver以linux文件的形式在本地硬盘上存储chunk,并且依据chunk handler和byte range来对chunk进行读取或写入操作。 为了方便使用,每个chunk都会被复制在多个chunk server上,默认情况下每个chunk会被复制三份。 用户可以自行设置不同的复制级别和次数。
Master节点存储了所有文件系统的metadata,包括命名空间,访问控制,文件到chunk的映射关系,以及所有chunk的文件路径。Master节点还负责管控系统级别的操作,如chunck lease management,garbage collection of orphaned chunks 和 chunk migration between chunkservers. Master节点会定期通过心跳包来向chunk server下达指令以及收集chunk server的当前状态。
链接到上层应用中的GFS客户端代码实现了文件系统的相关API,并且根据上层应用的实现方式来与Master节点和chunk servers进行交互。 当clients需要操作metadata时,会与Master进行交互,需要操作文件数据时,会直接与chunkserver进行通信。
clients和chunkservers都不会缓存任何文件数据。 client不需要缓存数据是因为目前大多数应用操作的文件对象都十分巨大,缓存的收益很低。 client不缓存数据大大简化了client的复杂度,并且消除了cache冲突的问题(client会缓存metadata)。Chunkserver不需要缓存数据的原因是chunks都作为linux file存储在本地空间中,Linux buffer cache会讲经常访问的内容缓存在内存中。
Single Master
为了避免读写操作成为Master节点的性能瓶颈,GFS的设计要求Master节点尽量少的参与到读写操作中。Clients不直接通过Master进行读写数据操作,而是询问Master哪个应该访问哪个ChunkServer,并会缓存一定时间的chunkserver信息。
下面用一个例子来解释client是如何完成一次简单的读操作的,具体过程如上图所示。 首先,client将application定义的file name和byte offset转换为chunk index。 client向master发送包含file name和chunk index的请求,查询该从哪个chunkserver查询数据。Master会应答client的请求,包含chunk handler以及所有replica的位置。client收到答复后,会将答复进行缓存(以file name和chunk index作为key)。其次,client会向包含数据的最近的chunkserver发送读请求,请求参数包括chunk handler和chunk内的byte range。由于client中已经缓存了chunk handler等数据,因此在缓存失效前,对同一个chunk发起的读写请求将不需要再与master进行交互。在GFS的设计中,client在一个请求中可以查询多个chunk所在位置,master也可以一次回复多个查询。
Chunk Size
GFS中的chunk size大小为64MB,远大于文件系统中一个block size的大小。GFS中的每个chunk就是一个linux file。 chunk size设置的比较大有很多优点:
- 减少client与master进行通信的次数
- 通过与chunkserver保持TCP连接来减少网络开销,因为读写操作大概率发生在一个chunk上
- 减少metadata的大小
大chunksize会带来hot spot问题。 由于chunksize比较大,因此一个较小的文件可能只包含极少的chunks。如果大量的client都要访问这个文件,存储这些chunks的chunkserver就会过载,成为hotspot。GFS的解决思路是可以将这种chunks进行大量的复制,从而做到负载均衡。
大chunksize同样会带来int