![Git][git]

上传流程

  • 1.根namenode通信请求上传文件,namenode检查目标文件是否已存在,父目录是否存在。
  • 2.namenode返回是否可以上传
  • 3.client请求第一个 block该传输到哪些datanode服务器上

  • 4.namenode返回3个datanode服务器ABC
  • 5.client请求3台dn中的一台A上传数据(本质上是一个RPC调用,建立pipeline),A收到请求会继续调用B,然后B调用C,将这个pipeline建立完成,逐级返回客户端
  • 6.client开始往A上传第一个block(先从磁盘读取数据放到一个本地内存缓存),以packet为单位,A收到一个packet就会传给B,B传给C;A每传一个packet会放入一个应答队列等待应答
  • 7.当一个block传输完成之后,client再次请求namenode上传第二个block的服务器。

    读取流程

    客户端读取HDFS数据相比写入数据要简单一些,以下是读取数据步骤:
  • 1.client访问NameNode,查询元数据信息,获得这个文件的数据块位置列表,返回输入流对象。
  • 2.就近挑选一台datanode服务器,请求建立输入流。
  • 3.开始读取这个数据的第一个block块,读取完全之后,开始接着读取这个文件的第二个block,直至把这个数据所有的block都读完了则文件读取完全了。
  • 4.数据读完之后关闭流连接。
  • 5.如果读取过程当中读取失败,将会依次读取该数据块的下一个副本,失败的节点将会被记录,不再连接。

# SecondaryNameNode
SecondaryNameNode 是 HDFS 架构中的一个组成部分,它用来保存名称节点中对HDFS元数据信息的备份,减小Editlog文件大小,从而缩短名称节点重启的时间。 它一般是单独运行在一台机器上。 SecondaryNameNode让EditLog变小的工作流程如下:

  • (1)SecondaryNameNode 会定期和 NameNode 通信,请求其停止使用 EditLog 文件,暂时将 新的写操作写到一个新的文件 edit.new 中,这个操作是瞬间完成的,上层写日志的函数完全感觉不到差别。
  • (2) SecondaryNameNode 通过 HTTP GET 方式从 NameNode 上获取到 Fslmage 和 EditLog 文 件,井下载到本地的相应目录下。
  • (3) SecondaryNameNode 将下载下来的 Fslmage 载入到内存,然后一条一条地执行 EditLog 文件中的各项更新操作,使内存中的 Fslmage 保持最新。 这个过程就是 EditLog 和 Fslmage 文件合 井。
  • (4) SecondaryNameNode 执行完(3)操作之后,会通过 post 方式将新的 Fslmage 文件发送 到 NameNode 节点上
  • (5) NameNode 将从 SecondaryNameNode 接收到的新的 Fslmage 替换旧的 Fslmage 文件,同 时将 Edit.new 替换 EditLog 文件,从而减小 EditLog 文件大小。

    从上面的过程可以看出,第二名称节点相当于为名称节点设置一个“检查点” ,周期性备份 名称节点中的元数据信息,但第二名称节点在 HDFS 设计中只是一个冷备份,并不能起到“热备 份”的作用。 HDFS 设计并不支持当名称节点故障时直接切换到第二名称节点。

HDFS Federation
HDFSl.O 的单 NameNode 设计不仅存在单点故障问题,还存在可扩展性和性能问题。只有一 个 NameNode, 不利于水平扩展。 HDFS Federation (HDFS 联邦)特性允许一个 HDFS 集群中存在 多个 NameNode 同时对外提供服务,这些 NameNode 分管一部分目录(水平切分),彼此之间相 互隔离,但共享底层的 DataNode 存储资源。每个 NameNode 是独立的,不需要和其他 Nam巳Node 协调合作。 如图 4-5 所示 , Federation 使用了 多 个独立的 NameNode/NameSpace 命名空间。这些 NameNode 之间是联合的,也就是说, 它们之间相互独立且不需要互相协调,各自分工管理自己的 区域。分布式的 DataNode 被用作通用的数据块存储设备。每个 DataNode 要向集群中所有的 NameNode 注册,且周期性地向所有 NameNode 发送心跳和块报告, 并执行来自所有 NameNode 的命令。每一个 DataNode 作为统一的块存储设备被所有 NameNode 节点使用。 每一个 DataNode 节点都在所有的 NameNode 进行注册。 DataNode 发送心跳信息、块报告到 所有 NameNode,同时执行所有 NameNode 发来的命令。