Hadoop系列 : HDFS(Hadoop Distributed File System)基本功能及原理

一 、HDFS的基本概念

HDFS有三个基本概念 , 数据块(Block) , 管理节点(NameNode) , 数据节点(DataNode)

  • 数据块(Block)
    HDFS默认的基本存储单元是64M的数据块

  • 元数据节点(NameNode)
    又名管理节点 , 它存储了文件与数据块的映射 , 以及数据块和数据节点的映射
    所有的文件和文件夹的元数据保存在一个文件系统树中
    这些信息也会在硬盘上保存成以下文件 , 命名空间镜像(namespace image)及修改日志(edit log)
    文件与数据块的映射并不存储在硬盘上 , 而是系统启动的时候从数据节点收集而来

    • 从元数据节点(Secondary NameNode)
      从元数据节点不是管理节点出问题时的备用节点 , 它和管理节点负责不同的任务
      主要功能是周期性地将管理节点的命名空间镜像文件和修改日志文件合并 , 防止日志文件过大
      合并过后的命名空间镜像文件也在管理节点保存了一份 , 管理节点宕机后可以用它来恢复
  • 数据节点(DataNode)
    数据节点是真正存储数据的地方
    客户端或者管理节点 , 可以向数据节点请求写入或者读取数据块
    数据节点会周期性地向管理节点回报它存储的数据块信息

二、元数据节点文件结构

$(dfs.name.dir)/current/VERSION
			    /edits
		  	    /fsimage
 			    /fstime

Version
Java Properties文件 , 保存了命令空间ID、HDFS的版本号等基本信息

namespaceID=858184872
clusterID=CID-251b606c-9a4a-4745-b24c-ff36ee801bd5 
cTime=1545648306166
storageType=NAME_NODE
blockpoolID=BP-1548290972-192.168.1.245-1545648306166
layoutVersion=-63

edits
操作日志文件

fsimage
元数据镜像文件 , 由从元数据节点维护

fstime
保存最近一次checkpoint的时间 , checkpoint默认是3600秒 , 也就是说每隔1小时 , 从元数据节点就要下载fsimage和eidits , 进行数据同步

三、文件系统命名空间映像文件及修改日志

从元数据节点合并fsimage流程
如图示 ,

  1. 从元数据节点通知元数据节点切换edits文件
  2. 从元数据节点从元数据节点获得fsimage和edits(通过http get)
  3. 从元数据节点将fsimage载入内存 , 然后开始合并edits
  4. 从元数据节点将新的fsimage发回给元数据节点
  5. 元数据节点将旧fsimage替换为新fsimage

四、数据流

文件读取的过程
HDFS文件读取流程
如图示 :

  1. 客户端调用DFS的open()函数
  2. DFS用RPC调用元数据节点 , 得到文件的数据块信息
  3. 元数据节点返回保存数据块的数据节点的地址
  4. DFS返回FSDataqInputStream给客户端 , 用来读取数据
  5. 客户端调用stream的read()函数开始读取数据

文件写入的过程
HDFS文件写入流程
如图示:

  1. 客户端调用DFS的create()来创建文件
  2. DFS用RPC调用元数据节点 , 在文件系统的命名空间中创建一个新的文件
  3. 元数据节点首先确定文件原来不存在 , 并且客户端有创建文件的权限 , 然后创建新文件
  4. DFS返回FSDataOutputStream给客户端
  5. 客户端通过FSDataOutputStream写入数据 , FSDataOutputStream将数据分成块 , 写入data queue
  6. data queue由DataStreamer读取 , 并通知元数据节点分配数据节点 , 用来存储数据块(每块默认复制3块) , 分配的数据节点放在一个pipeline里
  7. DataStreamer将数据块写入pipline中的第一个数据节点 , 第一个数据节点将数据块发送给第二个数据节点 , 第二个数据节点发送给第三个数据节点
  8. FSDataOutputStream为发出去的数据块保存到ack queue , 等待pipeline中的数据节点告知数据已经写入成功。
  9. 如果数据节点在写入过程中失败
    a. 关闭pipeline , 将ack queue中的数据放入data queue
    b. 当前的数据块在已经写入的数据节点中被元数据节点赋予新的标示 , 则错误节点重启后能发现数据块是过时的 , 会被删除
    c. 失败的数据节点从pipeline移除 , 另外的数据块则写入pipeline中的另外两个数据节点
    d. 元数据节点则被通知次数据块复制数量不足 , 将来会再创建第三份备份
  10. 当客户端结束写入数据 , 则调用stream的close函数 , 这个操作将所有的数据块写入pipeline中的数据节点 , 并等待ack queue返回成功 , 最后通知元数据节点写入完毕

猜你喜欢

转载自blog.csdn.net/qq_40651717/article/details/85247669
今日推荐