「后端分布式系列」前面关于 HDFS 的一些文章介绍了它的整体架构和一些关键部件的设计实现要点。

我们知道 HDFS 最早是根据 GFS(Google File System)的论文概念模型来设计实现的。

然后呢,我就去把 GFS 的原始论文找出来仔细看了遍,GFS 的整体架构图如下:

HDFS 参照了它所以大部分架构设计概念是类似的,比如 HDFS NameNode 相当于 GFS Master,HDFS DataNode 相当于 GFS chunkserver。

但还有些细节不同的地方,所以本文主要分析下不同的地方。

写入模型

HDFS 在考虑写入模型时做了一个简化,就是同一时刻只允许一个写入者或追加者。

在这个模型下同一个文件同一个时刻只允许一个客户端写入或追加。

而 GFS 则允许同一时刻多个客户端并发写入或追加同一文件。

允许并发写入带来了更复杂的一致性问题。

多个客户端并发写入时,它们之间的顺序是无法保证的,同一个客户端连续追加成功的多个记录也可能被打断。

这意味着一个客户端在连续写入文件数据时,它的数据最终在文件中的分布可能是不连续的。

所谓一致性就是,对同一个文件,所有的客户端看到的数据是一致的,不管它们是从哪个副本读取的。

如果允许多个客户端同时写一个文件,怎么保证写入数据在多个副本间一致?

我们前面讲 HDFS 时它只允许一个写入者按流水线方式写入多个副本,写入顺序一致,写入完成后数据将保持最终一致。

而对多个客户端而言,就必须让所有同时写入的客户端按同一种流水线方式去写入,才可能保证写入顺序一致。

这个写入流程我们下一节详细分析。

写入流程

GFS 使用租约机制来保障在跨多个副本的数据写入中保持顺序一致性。

GFS Master 将 chunk 租约发放给其中一个副本,这个副本我们就称为主副本,其他副本称为次副本。

由主副本来确定一个针对该 chunk 的写入顺序,次副本则遵守这个顺序,这样就保障了全局顺序一致性。

chunk 租约机制的设计主要是为了减轻 Master 的负担,由主副本所在的 chunkserver 来承担流水线顺序的安排。

如下图,我们详细描述下这个过程。

  1. 客户端请求 Master 询问哪个 chunkserver 持有租约以及其他副本的位置。

    如果没有 chunkserver 持有租约,说明该 chunk 最近没有写操作。

    Master 则选择将租约授权给其中一台 chunkserver。
  2. Master 返回客户端主副本和次副本的位置信息。

    客户端缓存这些信息以备将来使用。

    客户端以后不再需要联系 Master,除非主副本所在 chunkserver 不可用或返回租约过期了。
  3. 客户端选择最优的网络顺序推送数据,chunkserver 将数据先缓存在内部的 LRU 缓存中。

    GFS 中采用数据流和控制流分离的方法,从而能够基于网络拓扑结构更好地调度数据流的传输。
  4. 一旦所有的副本确认收到了数据,客户端将发送一个写请求控制命令到主副本。

    由主副本分配连续的序列号来确定最终的写入顺序。
  5. 主副本转发写请求到所有次副本,次副本按主副本安排的顺序执行写入操作。
  6. 次副本写完后向主副本应答确认操作完成。
  7. 最后主副本应答客户端,若任意副本写入过程中出现错误,将报告给客户端,由客户端发起重试。

GFS 和 HDFS 的写入流程都采用了流水线方式,但 HDFS 没有分离数据流和控制流。

HDFS 的数据流水线写入在网络上的传输顺序与最终写入文件的顺序一致。

而 GFS 数据在网络上的传输顺序与最终写入文件的顺序可能不一致。

GFS 在支持并发写入和优化网络数据传输方面做出了最佳的折衷。

总结

GFS 的论文发表于 2003 年,后来大部分的分布式文件系统设计实现或多或少都参考了 GFS 的设计思路。

而 HDFS 算是开源分布式文件系统中最完整实现了 GFS 论文中的概念模型。

但 HDFS 依然简化了 GFS 中关于并发写的思路,本文就两者的写入模型和过程做了一些对比说明,并希望引发一些思考。

参考

[1] Sanjay Ghemawat, Howard Gobioff, and Shun-Tak Leung. The Google File System

[2] Hadoop Documentation. HDFS Architecture.

[3] Robert Chansler, Hairong Kuang, Sanjay Radia, Konstantin Shvachko, and Suresh Srinivas. The Hadoop Distributed File System

[4] Tom White. Hadoop: The Definitive Guide. O’Reilly Media(2012-05), pp 94-96

[5] Yongjun Zhang. Understanding HDFS Recovery Processes

[6] Hairong
Kuang,
Konstantin
Shvachko,
Nicholas
Sze,
Sanjay
Radia,
 Robert
Chansler
, Yahoo!
HDFS
team
 Design Specification: Append/Hflush/Read
Design


[7] HDFSteam. Design Specification: HDFS Append and Truncates


下面是我的微信公众号 [瞬息之间],除了写技术的文章、还有产品的、行业和人生的思考,希望能和更多走在这条路上同行者交流,有兴趣可关注一下,谢谢。

后端分布式系列:分布式存储-HDFS 与 GFS 的设计差异的更多相关文章

  1. HDFS 与 GFS 的设计差异

    后端分布式系列」前面关于 HDFS 的一些文章介绍了它的整体架构和一些关键部件的设计实现要点. 我们知道 HDFS 最早是根据 GFS(Google File System)的论文概念模型来设计实现的 ...

  2. 后端分布式系列:分布式存储-HDFS NameNode 设计实现解析

    接前文 分布式存储-HDFS 架构解析,我们总体分析了 HDFS 架构的主要构成组件包括:NameNode.DataNode 和 Client.本文首先进一步解析 HDFS NameNode 的设计和 ...

  3. 后端分布式系列:分布式存储-HDFS 架构解析

    本文以 Hadoop 提供的分布式文件系统(HDFS)为例来进一步展开解析分布式存储服务架构设计的要点. 架构目标 任何一种软件框架或服务都是为了解决特定问题而产生的.还记得我们在 <分布式存储 ...

  4. 后端分布式系列:分布式存储-HDFS 异常处理与恢复

    在前面的文章 <HDFS DataNode 设计实现解析>中我们对文件操作进行了描述,但并未展开讲述其中涉及的异常错误处理与恢复机制.本文将深入探讨 HDFS 文件操作涉及的错误处理与恢复 ...

  5. 后端分布式系列:分布式存储-MySQL 数据库事务与复制

    好久没有写技术文章了,因为一直在思考 「后端分布式」这个系列到底怎么写才合适.最近基本想清楚了,「后端分布式」包括「分布式存储」和 「分布式计算」两大类.结合实际工作中碰到的问题,以寻找答案的方式来剖 ...

  6. 后端分布式系列:分布式存储-HDFS DataNode 设计实现解析

    前文分析了 NameNode,本文进一步解析 DataNode 的设计和实现要点. 文件存储 DataNode 正如其名是负责存储文件数据的节点.HDFS 中文件的存储方式是将文件按块(block)切 ...

  7. 后端分布式系列:分布式存储-HDFS Client 设计实现解析

    前面对 HDFS NameNode 和 DataNode 的架构设计实现要点做了介绍,本文对 HDFS 最后一个主要构成组件 Client 做进一步解析. 流式读取 HDFS Client 为客户端应 ...

  8. 分布式文件系统比较出名的有HDFS  和 GFS

    分布式文件系统比较出名的有HDFS  和 GFS,其中HDFS比较简单一点.本文是一篇描述非常简洁易懂的漫画形式讲解HDFS的原理.比一般PPT要通俗易懂很多.不难得的学习资料. 1.三个部分: 客户 ...

  9. 分布式文件管理系统HDFS

    Hadoop 分布式文件管理系统HDFS可以部署在廉价硬件之上,能够高容错. 可靠地存储海量数据(可以达到TB甚至PB级),它还可以和Yam中的MapReduce 编程模型很好地结合,为应用程序提供高 ...

随机推荐

  1. HTTPS介绍

    超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂 ...

  2. Python中模块之logging & subprocess的讲解

    subprocess & logging模块的介绍 1. subprocess 该模块替代了os.system & os.pawn*所实现的功能. 2. logging 1. 日志五大 ...

  3. 《Java技术》第三次作业

    (一)学习总结 1.阅读下面程序,分析是否能编译通过?如果不能,说明原因.应该如何修改?程序的运行结果是什么?为什么子类的构造方法在运行之前,必须调用父 类的构造方法?能不能反过来? class Gr ...

  4. C语言程序设计第二次作业—————顺序结构改

    1.输出带框文字:在屏幕上输出以下3行信息. ************* Welcome ************* 源程序 #include <stido.h> int mian() { ...

  5. c# 判断datatable中是否存在某列

    if (datatable.columns.contains("要找的列名"))

  6. Socket.io应用之联网拖拽游戏

    服务器端代码: const express=require('express'); const http=require('http'); const sio=require('socket.io') ...

  7. setTimeout、setInterval被遗忘的第三个参数

    一.最近在看promise,惊奇的发现:原来 setTimeout不只有两个参数,我还能说什么呢?赶紧探探究竟. function multiply(input) { return new Promi ...

  8. SVN冲突解决

    问题一.执行SVN commit时候,会生成除正常文件之外.mine..r3439 ..r3368的三个文件 .mine:是自己要提交的版本 .r3439:在别人之前提交的版本 .r3368:初始版本 ...

  9. EF实体的部分更新

    实现实体的部分更新假设实体InfoHotel如下: public class InfoHotel { public int Id{get;set;} public string Name{get;se ...

  10. C/C++静态数组与动态数组的区别

    简介 以下三行代码有什么区别? int a[10]; int *a = (int*)malloc(sizeof(int)*10); int *a = new int[10]; 第一行代码定义a为包含1 ...