The Google File System 翻译和理解( 二 )

2.2 接口GFS 提供了常见的文件系统接口 , 文件被存放到目录中 , 并由路径名进行标识 。我们支持常见的操作如createdeleteopencloseread以及write文件 。
特殊地,GFS 还有**快照 snapshot **和 记录追加 record append 操作 。

  • 快照低开销地创建了一个文件或目录树的拷贝 。
  • 记录追加允许多个客户端同时向一个文件追加数据,并保证每个单独的客户端追加操作的原子性 。可以用于实现多路结果合并和生产者-消费者队列 , 它们使很多客户端在不加锁的情况下可以同时进行追加操作 。
2.3 架构一个 GFS 集群由一个 Master 和多个块服务器 chunkservers 组成,可以被多个客户端访问 。每个节点都是一个运行在 Linux 上的普通进程 。
The Google File System 翻译和理解

文章插图
GFS 文件被划分为固定大小的块,每个块由一个不变的、全局唯一的 64bit 块句柄标识,它是由主节点在创建块时分配的 。块服务器存储这些块并对其进行读写操作,为了提高可靠性,每个块都会在多个块服务器上进行复制 。默认情况下 , 我们会存储三个副本 , 用户也可以对不同的命名空间设置不同的复制级别 。
Master 存储了整个文件系统的元数据,包含命名空间、访问控制信息、文件到块的映射,以及块的当前位置等等 。它也控制了一些系统层的行为,如块的租约管理,孤儿块的垃圾回收,以及块服务器之间的块迁移 。Master 周期性地与每个块节点进行通信,通过心跳信息发送指令并收集块服务器状态 。
GFS 客户端代码嵌入到应用中,实现了文件系统 API , 代表客户端进行读写数据,与主节点和块服务器进行通信 。客户端与主节点进行元数据的交互操作,而与数据相关的通信则直接与块服务器进行 。
2.4 单一的主节点单一的主节点简化了我们的设计,令主节点能够根据整体信息确定块的位置,以及进行复制决策 。
由于主节点是单一的,我们必须最小化对主节点的读写操作,以保证它不会成为系统性能的瓶颈 。客户端不会通过主节点读写数据,而只会向主节点询问需要与哪些块服务器进行联系 。客户端会将主节点的答复缓存一段时间,并在后续直接和块服务器交互 。
The Google File System 翻译和理解

文章插图
简单解释一下上图中的一个读操作交互 。
  1. 首先 , 使用固定的块大小,客户端将文件名和应用指定的字节便宜转换为文件块的索引 。
  2. 然后,它向主节点发送一个包含文件名和块索引的请求 , 主节点回复相应的块句柄和副本的位置 。客户端使用文件名和块索引作为 Key 缓存这条信息 。
  3. 客户端向其中一个副本发送请求,大多数时候选择最近的那个 。请求指定了块句柄和那个块的一个字节范围 。后续客户端无需和主节点交互 , 除非缓存信息过期或文件被重新打开 。
    事实上,客户端通常在一个请求中询问多个块,主节点的回复也会包含紧跟在请求块后面的块的信息,这在实际中往往可以在未来减少一些客户端-主节点通信 。
2.5 块大小块大小是设计的关键参数,我们选择 64MB,这要比一般文件系统的块要大许多 。每个块副本在块服务器上被存储为一个普通的 Linux 文件,只有在需要时才扩大 。
令块的大小很大的最大隐患在于内部碎片 。GFS 使用惰性空间分配避免了因内部碎片带来的空间浪费 。
采用大小比较大的块有以下几个重要优点:
  • 它能减少客户端和主节点的交互次数,因为一个块的位置信息代表了更多的数据的位置 。
  • 由于大的块大小,客户端能在一个块上进行更多操作 。这样可以通过与块服务器在一段时间内保持一个 TCP 长连接赖减少网络开销 。
  • 主节点可以存储更少的元数据,这样我们可以把元数据存储在内存中 。所带来的好处在 2.6.1 节中讨论 。
采用大小大的块也有下面这个缺点:
当大量客户端访问相同的文件时,存储这个块的块服务器会成为热点 。显然当块的大小比较大,出现热点块服务器的概率也就更大 。
在实际中,热点不是一个主要问题,因为我们的应用大多会顺序读取大量的包含多个块的文件 。
但是当 GFS 第一次用于一个批处理序列系统时,还是发生了热点问题:一个可执行文件以单个块的形式写入 GFS,然后在数百台机器上同时启动 。少量的存储这个文件的块服务器会由于数百台机器的同时访问而过载 。我们通过以下两个手段解决这个问题:

推荐阅读