系统由一个master以及多个chunkserver构成. 一个文件被切分红多个大小固定的chunk(默认64MB)并将多个备份(默认3个)存储在不一样的chunkserver上.算法
master存储文件系统的metadata, 包括namespace, access control information, mapping from file to chunks, current locations of chunks.缓存
master周期性的与chunkserver经过心跳包下达指令并监测状态.安全
client与master通讯得到文件的metadata并缓存后与chunkserver直接通讯进行读写.网络
chunk size设置为远超常见的文件系统的64MB, 而且只在须要是分配新的chunk. 较大的chunk size对于系统既有好处亦有坏处.数据结构
优势:架构
缺点:并发
master将三类metadata维持在内存中, 包括namespace, access control information, mapping from file to chunks, current locations of chunks.app
namespace以及access control information经过operation log持久化存储在master的本地磁盘上并在远端备份.负载均衡
current locations of chunks在master启动时以及新chunkserver加入时主动询问.dom
metadata被严格限制所有维持在内存中, 减小了master操做的时间, 但内存大小限制了GFS存储数据的大小.
实际上对metadata的存储作了不少压缩, 64MB的chunk能够经过小于64字节的数据维护, 而且经过拓展内存来支持更大容量十分低廉.
master启动时, 以及有新的chunkserver加入时, master会主动询问并存储chunk location.
因为master控制chunk的置放而且经过心跳包监测, 能够维持chunk locations信息处在最新态.
operation log记录了metadata的更新, 而且做为逻辑时间线定义并发操做的顺序. 文件, chunk以及其版本号经过建立时的逻辑时间统一管理.
operation log自己须要可靠存储, 而且在metadata的更新持久化前保证对客户端的不可见. 不然master的宕机可能会致使文件或操做的丢失.
所以operation log被存储在多个机器上, 而且只在本地以及远端记录成功后才会回应client的操做.
master宕机时经过重作operation log重启, 为了保证重启的速度, 当operation log达到必定的大小时须要对master的状态作checkpoint, 重启只需重作operation log中逻辑时间线在最近checkpoint建立时以后的.
当checkpoint建立时失败, 只需从上次checkpoint处恢复, 虽然可能会增长恢复时间, 但依旧能保证可靠性.
namespace的更新由master保证原子性, 而且由operation log提供可靠性.
consistent: client在全部的副本中看到的数据是相同的.
defined: client写入的数据可以完整的被看到.
对于record append, 保证appended atomically at least once. GFS可能会在多个defined region之间插入padding以及record duplicates致使inconsistent. 但GFS可以监测到这部分数据并管理, 最终对client是不可见的.
并发更新操做在operation log里得到逻辑顺序并执行, 并经过chunk version检测chunk的数据是否落后, 落后的数据再也不参与更新操做而且master不会返回其chunk location, 它等待下一次的垃圾回收.
因为client会缓存metadata, 那么就有可能直接访问包含落后数据的chunk. 过时时间以及打开文件会致使client从新向master请求metadata. 另外, 当操做为append时, 落后的chunk会返回异常的文件结尾, 致使client从新向master请求metadata.
为了解决组件失效带来的存储数据失败, GFS会经过校验和检测到, 并经过备份副本尽快恢复. 当全部备份都不可用时, 数据真正的丢失. 但此时依旧只会收到异常而不是未知的数据.
为了保证数据的一致性, 更新操做须要在全部的副本中以相同的顺序执行. 为了减小master的负载, master将chunk的某个副本指认为primary, 并具备必定的过时时间, 全部的更新操做由primary统一管理. client的更新请求直接交付给primary replica.
另外, 在跨chunk写时, 操做会被切分, 致使会出现写覆盖的状况, 但仍能保证consistent.
流程与写入流程相似, 但为了保证原子性, primary在写入时检查chunk剩余容量是否能容纳这次操做的数据. 若是不能, primary以及secondaries将会填充直到chunk满, 并通知client重试操做. 这样操做就会落到下次请求时建立的新chunk内了.
master对namespace的管理不采用前缀式的数据结构管理(相似字典树), 但采用前缀压缩算法节省空间, 同时每一个结点也含有一个读写锁.
当须要对namespace进行更新时, 由根目录开始不断获取读锁直到目标路径的上一级, 再获取目标路径的写锁. 为了不获取锁时死锁, 获取锁的顺序必须严格按照namespace层次进行.
master建立chunk时, 依据如下原则选择chunkserver
当可用备份数量小于目标数量时, 须要re-replicate, 当多个chunk须要re-replicate时, 根据如下因素排序
在复制时, 对选择哪一个副本进行复制时, 依据如下因素选择
master周期性地对副本进行负载均衡, 它检查当前的副本分布状况, 而后移动副本以便更好的利用硬盘空间, 更有效的进行负载均衡.
master移走那些剩余空间低于平均值的chunkserver上的副本, 从而平衡系统总体的硬盘使用率.
GFS 在文件删除后不会马上回收物理空间, 只在文件和 Chunk 级的常规垃圾收集时进行.
当文件被应用程序删除时, master首先记录到operation log中, 后将文件名改成包含删除时间的隐藏名. 当master对namespace常规扫描时, 自动删除必定天数前的隐藏文件的元数据. 所以在删除元数据前, 能够经过重命名的方式撤销删除.
另外在常规扫描中, master会删除不被任何文件引用的chunk的元数据, 并在心跳信息中告知chunkserver哪些属于它的chunk元数据已经不存在了, chunkserver可自行删除.
垃圾回收相较于直接删除有以下几个优点:
垃圾回收的主要问题是会致使用户调优存储空间的利用率. 重复建立和删除临时文件将致使大量的存储空间没法当即重用. 能够经过显示的再次删除以加速时间, 或者对namespace采用不一样的复制和回收策略.
在master签定租约, chunk复制时都会附带chunk的版本号. client和chunkserver会在操做时验证版本号以保证访问的chunk数据是最新的.
当master进程失效后, 能够依据operation log以及checkpoint快速重启.
当master所在机器宕机后, 因为operation log是多机器备份的, 所以能够在其余机器上从新启动master进程.
另外还存在shadow master, 他们在master机器宕机后提供文件系统的只读访问. 在master正常运行时, 他们和master以及chunkserver通讯以更新元数据. shadow master没法保证元数据永远是最新的, 但文件内容是不会过时的.