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


  • 提高可执行文件的复制因子 replication factor 。让更多的块服务器存储这些热点数据 。
  • 令批处理序列系统和应用程序不同时, 而是交替启动 。
一个可能的长期的解决方案是让客户端能从其他客户端读取数据 。
2.6 元数据主节点存储了三种主要类型的元数据:文件和块的命名空间,文件到块的映射,以及每个块副本的位置,所有元数据都保留在主节点的内存中 。
命名空间,以及文件到块的映射,通过将操作记录存储在本地磁盘上的日志文件中得以永久保存,并在远程的机器上进行日志备份 。使用日志使我们能够简单可靠地更新主节点状态,并且不用担心主节点崩溃造成的不一致 。主节点不会永久保存块位置信息,而会在启动时,以及有新的块服务器加入集群时,询问每个块服务器的块信息 。
2.6.1 内存中的数据结构得益于元数据存放在内存中,主节点的操作非常快 。它也能使主节点能够周期性地在后台简单有效的地浏览整个系统的状态 。这个周期性的浏览操作用于实现块的垃圾回收、块服务器出错后的重复制,负载均衡和磁盘空间使用的块迁移,4.3 和 4.4 节会深入的讨论这些行为 。
但将元数据放在内存中有一个潜在问题 , 即块的数量和将来整个系统的容量受到主节点的内存大小限制 。但由于块的元数据大小实际很?。栽谑导手姓獠皇且桓鲅现氐奈侍?。更何况,即使需要为主服务器增加额外的内存,这个花费相比将元数据存放在内存中带来的简单性、可靠性、有效性和扩展性来说,也是很值得的 。
2.6.2 块位置主节点不会永久保留类似哪些块服务器含有一个给定的块的记录这样的信息 。而是在启动时轮询块服务器获取这些信息 。主节点可以将自己保持在最新状态,因为它控制所有块的放置,并且通过常规的心跳消息来监控块服务器的状态 。
起初我们考虑在主节点永久地保存块位置信息,但后来发现在启动时向块服务器请求数据并在此后进行周期性更新要简单许多 。这消除了当块服务器加入或离开集群、更改名字、出错、重启等异常发生时,保持主节点和块服务器同步的问题 。在大型集群中这些问题发生得很频繁 。
理解这种设计的另一个角度是:认识到块服务器对他的磁盘上最终存储或不存储某个块有最终的决定权 。在主节点上维护这些信息的一致性视图是没有意义的,因为块服务器上的错误可能会导致块发生主服务器不能及时知悉的变动,例如块被删除或重命名等 。
2.6.3 操作日志操作日志包含了关键的元数据变化的历史记录,是 GFS 的核心 。它不仅永久的记录了元数据,还能提供确定并发操作顺序的逻辑时间线服务 。文件和块,连同它们的版本 , 都是由它们创建的逻辑时间唯一的、永久的进行标识的 。
因为操作日志是临界资源,我们必须可靠的存储它,在元数据的变化持久化之前,客户端是无法看到这些操作日志的 。否则,即使块本身保存下来,仍然有可能丢失整个文件系统或者客户端最近的操作 。因此,我们将它复制到几个远程的机器上,并在将相应的操作刷新(flush)到本地和远程磁盘后再回复客户端 。主节点会在刷新之前批处理一些日志记录 , 以此减少刷新和系统内复制对整个系统吞吐量的影响 。
主节点通过重新执行操作日志来恢复状态 。为了使启动时间尽量短,我们必须保持日志较小 。当日志超过一个特定的大小时,主节点会检查它的状态 。这样一来,以使它能够在足够小的代价下通过载入本地磁盘的最后一个检查点及之后的日志记录进行恢复 。检查点是一个类似 B 树的数据结构,能够直接映射到内存中,并且在用于命名空间查询时无需额外的解析 。这大大提高了恢复速度,增加了可用性 。
因为创建检查点需要一定的时间 , 所以主节点的内部状态会被格式化,格式化的结果保证了新检查点的创建不会阻塞正在进行的修改操作 。当主节点切换到新的日志文件时,GFS 通过另一个线程进行新检查点的创建 。新检查点包括切换前所有的修改操作 。对于一个有几百万文件的集群来说,创建一个新检查点大概需要1分钟 。当创建完成后,它将写入本地和远程磁盘 。
恢复只需要最近完成的检查点和在此之后的日志文件 。老的检查点和日志文件能够被删除 , 但为了应对灾难性故障,我们会保留其中的一部分 。检查点的失败不会影响恢复的正确性 , 因为恢复代码会探测并跳过未完成的检查点 。

推荐阅读