阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Hadoop学习:深度剖析HDFS原理

143次阅读
没有评论

共计 7013 个字符,预计需要花费 18 分钟才能阅读完成。

在配置 hbase 集群将 hdfs 挂接到其它镜像盘时,有不少困惑的地方,结合以前的资料再次学习;  大数据底层技术的三大基石起源于 Google 在 2006 年之前的三篇论文 GFS、Map-Reduce、Bigtable,其中 GFS、Map-Reduce 技术直接支持了 Apache Hadoop 项目的诞生,Bigtable 催生了 NoSQL 这个崭新的数据库领域,由于 map-Reduce 处理框架高延时的缺陷,Google 在 2009 年后推出的 Dremel 促使了实时计算系统的兴起,以此引发大数据第二波技术浪潮,一些大数据公司纷纷推出自己的大数据查询分析产品,如:Cloudera开源了大数据查询分析引擎 ImpalaHortonworks 开源了 StingerFackbook 开源了 Presto、UC Berkeley AMPLAB 实验室开发了Spark 计算框架,所有这些技术的数据来源均基于 hdsf, 对于 hdsf 最基本的不外乎就是其读写操作

目录:

  • hdfs 名词解释
  • hdsf 架构
  • NameNode(NN)
  • Secondary NN
  • hdfs 写文件
  • hdfs 读文件
  • block 持续化结构

HDFS 名词解释:


  • Block: 在 HDFS 中,每个文件都是采用的分块的方式存储,每个 block 放在不同的 datanode 上,每个 block 的标识是一个三元组(block id,numBytes,generationStamp),其中 block id 是具有唯一性,具体分配是由 namenode 节点设置,然后再由 datanode 上建立 block 文件,同时建立对应 block meta 文件
  • Packet:在 DFSclient 与 DataNode 之间通信的过程中,发送和接受数据过程都是以 一个 packet 为基础 的方式进行
  • Chunk:中文名字也可以称为块,但是为了与 block 区分,还是称之为 chunk。在 DFSClient 与 DataNode 之间通信的过程中,由于文件采用的是基于块的方式来进行的,但是在发送数据的过程中是以 packet 的方式来进行的,每个 packet 包含了多个 chunk,同时对于每个 chunk 进行 checksum 计算,生成 checksum bytes
  • 小结:
    1. 一个文件被拆成多个 block 持续化存储(block size 由配置文件参数决定)思考:修改 block size 对以前持续化的数据有何影响?
    2. 数据通讯过程中一个 block 被拆成 多个 packet
    3. 一个 packet 包含多个 chunk
  • Packet 结构与定义:Packet 分为两类,一类是实际数据包,另一类是 heatbeat 包。一个 Packet 数据包的组成结构,如图所示
  • Hadoop 学习:深度剖析 HDFS 原理
  • 上图中,一个 Packet 是由 Header 和 Data 两部分组成,其中 Header 部分包含了一个 Packet 的概要属性信息,如下表所示:
  • Hadoop 学习:深度剖析 HDFS 原理
  • Data 部分是一个 Packet 的实际数据部分,主要包括一个 4 字节校验和(Checksum)与一个 Chunk 部分,Chunk 部分最大为 512 字节
  • 在构建一个 Packet 的过程中,首先将字节流数据写入一个 buffer 缓冲区中,也就是从偏移量为 25 的位置(checksumStart)开始写 Packet 数据 Chunk 的 Checksum 部分,从偏移量为 533 的位置(dataStart)开始写 Packet 数据的 Chunk Data 部分,直到一个 Packet 创建完成为止。
  • 当写一个文件的最后一个 Block 的最后一个 Packet 时,如果一个 Packet 的大小未能达到最大长度,也就是上图对应的缓冲区中,Checksum 与 Chunk Data 之间还保留了一段未被写过的缓冲区位置,在发送这个 Packet 之前,会检查 Chunksum 与 Chunk Data 之间的缓冲区是否为空白缓冲区(gap),如果有则将 Chunk Data 部分向前移动,使得 Chunk Data 1 与 Chunk Checksum N 相邻,然后才会被发送到 DataNode 节点

hdsf 架构:


  • hdfs 的构架图网上一堆,抓了一张表述比较清楚的图如下, 主要包含因类角色:Client、NameNode、SecondayNameNode、DataNode
  • Hadoop 学习:深度剖析 HDFS 原理
  • HDFS Client: 系统使用者,调用 HDFS API 操作文件; 与 NN 交互获取文件元数据; 与DN 交互进行数据读写, 注意:写数据时文件 切分由 Client 完成 
  • Namenode:Master 节点(也称元数据节点),是系统唯一的管理者。负责元数据的管理 ( 名称空间和数据块映射信息 ); 配置 副本策略;处理客户端请求
  • Datanode:数据存储节点 (也称 Slave 节点), 存储实际的数据;执行 数据块的读写;汇报存储信息给 NN
  • Secondary NameNode:小弟角色,分担大哥 namenode 的工作量;是 NameNode 的冷备份;合并 fsimage 和 fsedits 然后再发给 namenode, 注意:在 hadoop 2.x 版本,当启用 hdfs ha 时,将没有这一角色。(详见第二单)
  • 解释说明:
    1. 热备份: b 是 a 的热备份,如果 a 坏掉。那么 b 马上运行代替 a 的工作
    2. 冷备份: b 是 a 的冷备份,如果 a 坏掉。那么 b 不能马上代替 a 工作。但是 b 上存储 a 的一些信息,减少 a 坏掉之后的损失
  • hdfs 构架原则:
    1. 元数据与数据分离:文件本身的属性(即元数据)与文件所持有的数据分离
    2. 主 / 从架构:一个 HDFS 集群是由一个 NameNode 和一定数目的 DataNode 组成
    3. 一次写入多次读取:HDFS 中的文件在任何时间只能有一个 Writer。当文件被创建,接着写入数据,最后,一旦文件被关闭,就不能再修改。
    4. 移动计算比移动数据更划算:数据运算,越靠近数据,执行运算的性能就越好,由于 hdfs 数据分布在不同机器上,要让网络的消耗最低,并提高系统的吞吐量,最佳方式是将运算的执行移到离它要处理的数据更近的地方,而不是移动数据

NameNode:


  • NameNode 是整个文件系统的管理节点,也是 HDFS 中最复杂的一个实体,它维护着 HDFS 文件系统中最重要的两个关系:
    1. HDFS 文件系统中的文件目录树,以及文件的数据块索引,即 每个文件对应的数据块列表
    2. 数据块和数据节点的对应关系,即某一块 数据块保存在哪些数据节点 的信息
  • 第一个关系即目录树、元数据和数据块的索引信息会 持久化到物理存储 中,实现是保存在命名空间的镜像 fsimage 和编辑 日志 edits中,注意:在 fsimage 中,并没有记录每一个 block 对应到哪几个 Datanodes 的对应表信息
  • 第二个关系是在 NameNode 启动后,每个 Datanode 对本地磁盘进行扫描,将 本 Datanode 上保存的 block 信息汇报给 Namenode,Namenode 在接收到每个 Datanode 的块信息汇报后,将接收到的块信息,以及其所在的 Datanode 信息等保存在内存中。HDFS 就是通过这种块信息汇报的方式来 完成 block -> Datanodes list 的对应表 构建
  • fsimage记录了自最后一次检查点之前 HDFS 文件系统中所有目录和文件的序列化信息;
  • edits是元数据操作日志(记录每次保存 fsimage 之后到下次保存之间的所有 hdfs 操作)
  • 在 NameNode 启动时候,会先将 fsimage 中的文件系统元数据信息 加载到内存 ,然后根据 eidts 中的记录将内存中的元数据 同步至最新状态,将这个新版本的 FsImage 从内存中保存到本地磁盘上,然后删除 旧的 Editlog,这个过程称为一个 检查 点 (checkpoint), 多长时间做一次 checkpoint?(见第四章 参数配置 checkpoint 能手工触发吗?验证重启 hdfs 服务后 editlog 没删除呢?
  • 类似于数据库中的检查点,为了避免 edits 日志过大,在 Hadoop1.X 中,SecondaryNameNode 会按照时间阈值(比如 24 小时)或者 edits 大小阈值(比如 1G),周期性的将 fsimage 和 edits 的合并,然后将最新的 fsimage 推送给 NameNode。而在 Hadoop2.X 中,这个动作是由 Standby NameNode 来完成.
  • 由此可看出,这两个文件一旦损坏或丢失,将导致整个 HDFS 文件系统不可用,在 HDP2.4 安装(五):集群及组件安装  集 群安装过程中,hdfs 默认的只能选择一个 NN,是否意味着 NN 存在单点呢?( 见第二单 hdfs HA)
  • 在 hadoop1.X 为了保证这两种元数据文件的高可用性,一般的做法,将dfs.namenode.name.dir 设置成以逗号分隔的多个目录,这多个目录至少不要在一块磁盘上,最好放在不同的机器上,比如:挂载一个共享文件系统
  • fsimage\edits 是序列化后的文件,想要查看或编辑里面的内容,可通过 hdfs 提供的 oiv\oev 命令,如下:
    • 命令: hdfs oiv(offline image viewer)用于将 fsimage 文件的内容转储到指定文件中以便于阅读,,如文本文件、XML 文件,该命令需要以下参数:
      1. -i  (必填参数)  –inputFile <arg>  输入 FSImage 文件
      2. -o (必填参数)  –outputFile <arg> 输出转换后的文件,如果存在,则会覆盖
      3. -p (可选参数)–processor <arg>  将 FSImage 文件转换成哪种格式:(Ls|XML|FileDistribution). 默认为 Ls
      4. 示例:hdfs oiv -i /data1/hadoop/dfs/name/current/fsimage_0000000000019372521 -o /home/hadoop/fsimage.txt
    • 命令:hdfs oev (offline edits viewer 离线 edits 查看器)的缩写,该工具只操作文件因而并不需要 hadoop 集群处于运行状态。
      1. 示例:  hdfs oev -i edits_0000000000000042778-0000000000000042779 -o edits.xml
      2. 支持的输出格式有binary(hadoop 使用的二进制格式)、xml(在不使用参数 p 时的默认输出格式)和stats(输出 edits 文件的统计信息)
  • 小结:
  1. NameNode 管理着 DataNode,接收 DataNode 的注册、心跳、数据块提交等信息的上报,并且在心跳中发送数据块复制、删除、恢复等指令;同时,NameNode 还为客户端对文件系统目录树的操作和对文件数据读写、对 HDFS 系统进行管理提供支持
  2. Namenode 启动后会进入一个称为 安全模式 的特殊状态。处于安全模式 的 Namenode 是不会进行数据块的复制的。Namenode 从所有的 Datanode 接收心跳信号和块状态报告。块状态报告包括了某个 Datanode 所有的数据 块列表。每个数据块都有一个指定的最小副本数。当 Namenode 检测确认某 个数据块的副本数目达到这个最小值,那么该数据块就会被认为是副本安全 (safely replicated) 的;在一定百分比(这个参数可配置)的数据块被 Namenode 检测确认是安全之后(加上一个额外的 30 秒等待时间),Namenode 将退出安全模式状态。接下来它会确定还有哪些数据块的副本没 有达到指定数目,并将这些数据块复制到其他 Datanode 上。

Secondary NameNode:在 HA cluster 中又称为 standby node


  • 定期合并 fsimage 和 edits 日志,将 edits 日志文件大小控制在一个限度下
  • Hadoop 学习:深度剖析 HDFS 原理
  • namenode 响应 Secondary namenode 请求,将 edit log 推送给 Secondary namenode,开始重新写一个新的 edit log
  • Secondary namenode 收到来自 namenode 的 fsimage 文件和 edit log
  • Secondary namenode 将 fsimage 加载到内存,应用 edit log,并生成一 个新的 fsimage 文件
  • Secondary namenode 将新的 fsimage 推送给 Namenode
  • Namenode 用新的 fsimage 取代旧的 fsimage,在 fstime 文件中记下检查 点发生的时

 HDFS 写文件:


  • 写文件部分参考 blog 地址(http://www.linuxidc.com/Linux/2016-09/134882.htm),2.X 版本默认 block 的大小是 128M(见第四章参数配置)
  • Hadoop 学习:深度剖析 HDFS 原理
  1. Client 将 FileA 按 64M 分块。分成两块,block1 和 Block2;
  2. Client 向 nameNode 发送写数据请求,如图蓝色虚线①——>
  3. NameNode 节点,记录 block 信息。并返回可用的 DataNode (NameNode 按什么规则返回 DataNode? 参见第三单 hadoop 机架感知),如粉色虚线②———>
    • Block1: host2,host1,host3
    • Block2: host7,host8,host4
  4. client 向 DataNode 发送 block1;发送过程是以流式写入,流式写入过程如下:
    1. 将 64M 的 block1 按 64k 的 packet 划分
    2. 然后将第一个 packet 发送给 host2
    3. host2 接收完后,将第一个 packet 发送给 host1,同时 client 想 host2 发送第二个 packet
    4. host1 接收完第一个 packet 后,发送给 host3,同时接收 host2 发来的第二个 packet
    5. 以此类推,如图红线实线所示,直到将 block1 发送完毕
    6. host2,host1,host3 向 NameNode,host2 向 Client 发送通知,说“消息发送完了”。如图粉红颜色实线所示
    7. client 收到 host2 发来的消息后,向 namenode 发送消息,说我写完了。这样就真完成了。如图黄色粗实线
    8. 发送完 block1 后,再向 host7,host8,host4 发送 block2,如图蓝色实线所示
  •  说明:
    1. 当客户端向 HDFS 文件写入数据的时候,一开始是写到本地临时文件中。假设该文件的副 本系数设置为 3,当本地临时文件累积到一个数据块的大小时,客户端会从 Namenode 获取一个 Datanode 列表用于存放副本。然后客户端开始向第一个 Datanode 传输数据,第一个 Datanode 一小部分一小部分 (4 KB) 地接收数据,将每一部分写入本地仓库,并同时传输该部分到列表中 第二个 Datanode 节点。第二个 Datanode 也是这样,一小部分一小部分地接收数据,写入本地 仓库,并同时传给第三个 Datanode。最后,第三个 Datanode 接收数据并存储在本地。因此,Datanode 能流水线式地从前一个节点接收数据,并在同时转发给下一个节点,数据以流水线的 方式从前一个 Datanode 复制到下一个
    2. 时序图如下:

Hadoop 学习:深度剖析 HDFS 原理

  •  小结:
    1. 写入的过程,按 hdsf 默认设置,1T 文件,我们需要 3T 的存储3T 的网络流量
    2. 在执行读或写的过程中,NameNode 和 DataNode 通过 HeartBeat 进行保存通信,确定 DataNode 活着。如果发现 DataNode 死掉了,就将死掉的 DataNode 上的数据,放到其他节点去。读取时,要读其他节点去
    3. 挂掉一个节点,没关系,还有其他节点可以备份;甚至,挂掉某一个机架,也没关系;其他机架上,也有备份

hdfs 读文件: 


  •  读到文件示意图如下:
  • Hadoop 学习:深度剖析 HDFS 原理
  • 客户端通过调用 FileSystem 对象的 open()方法来打开希望读取的文件,对于 HDFS 来说,这个对象时分布文件系统的一个实例;
  • DistributedFileSystem 通过使用 RPC 来调用 NameNode 以确定文件起始块的位置,同一 Block 按照重复数会返回多个位置,这些位置按照 Hadoop 集群拓扑结构排序,距离客户端近的排在前 面 (详见第三章
  • 前两步会返回一个 FSDataInputStream 对象,该对象会被封装成 DFSInputStream 对象,DFSInputStream 可以方便的管理 datanode 和 namenode 数据流,客户端对这个输入流调用 read()方法
  • 存储着文件起始块的 DataNode 地址的 DFSInputStream 随即连接距离最近的 DataNode,通过对数据流反复调用 read()方法,将数据从 DataNode 传输到客户端
  • 到达块的末端时,DFSInputStream 会关闭与该 DataNode 的连接,然后寻找下一个块的最佳 DataNode,这些操作对客户端来说是透明的,客户端的角度看来只是读一个持续不断的流
  • 一旦客户端完成读取,就对 FSDataInputStream 调用 close()方法关闭文件读取

block 持续化结构:


  •  DataNode 节点上一个 Block 持久化到磁盘上的物理存储结构,如下图所示:
  • Hadoop 学习:深度剖析 HDFS 原理
  • 每个 Block 文件(如上图中 blk_1084013198 文件)都对应一个 meta 文件(如上图中 blk_1084013198_10273532.meta 文件),Block 文件是一个一个 Chunk 的二进制数据 (每个 Chunk 的大小是 512 字节),而 meta 文件是与 每一个 Chunk 对应的 Checksum 数据,是序列化形式存储

更多 Hadoop 相关信息见Hadoop 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=13

本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-09/134881.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计7013字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中