共计 4236 个字符,预计需要花费 11 分钟才能阅读完成。
概览
首先我们来认识一下 HDFS,HDFS(Hadoop Distributed File System)Hadoop 分布式文件系统。它其实是将一个大文件分成若干块保存在不同服务器的多个节点中。通过联网让用户感觉像是在本地一样查看文件,为了降低文件丢失造成的错误,它会为每个小文件复制多个副本(默认为三个),以此来实现多机器上的多用户分享文件和存储空间。
HDFS 特点:
① 保存多个副本,且提供容错机制,副本丢失或宕机自动恢复。默认存 3 份。
② 运行在廉价的机器上。
③ 适合大数据的处理。因为小文件也占用一个块,小文件越多(1000 个 1k 文件)块越 多,NameNode 压力越大。
如:将一个大文件分成三块 A、B、C 的存储方式
PS:数据复制原则:
除了最后一个块之外的文件中的所有块都是相同的大小。
HDFS的放置策略:
是将一个副本放在本地机架中的一个节点上,另一个位于不同(远程)机架中的节点上,而最后一个位于不同节点上远程机架。
涉及到的属性:
块大小:Hadoop1 版本里默认为 64M,Hadoop2 版本里默认为 128M
复制因子:每个文件加上其文件副本的份数
HDFS的基本结构
如上图所示,HDFS 基本结构分 NameNode、SecondaryNameNode、DataNode 这几个。
NameNode:是 Master 节点,有点类似 Linux 里的根目录。管理数据块映射;处理客户端的读写请求;配置副本策略;管理 HDFS 的名称空间;
SecondaryNameNode:保存着 NameNode 的部分信息(不是全部信息 NameNode 宕掉之后恢复数据用),是 NameNode 的冷备份;合并 fsimage 和 edits 然后再发给 namenode。(防止 edits 过大的一种解决方案)
DataNode:负责存储 client 发来的数据块 block;执行数据块的读写操作。是 NameNode 的小弟。
热备份:b 是 a 的热备份,如果 a 坏掉。那么 b 马上运行代替 a 的工作。
冷备份:b 是 a 的冷备份,如果 a 坏掉。那么 b 不能马上代替 a 工作。但是 b 上存储 a 的一些信息,减少 a 坏掉之后的损失。
fsimage: 元数据镜像文件(文件系统的目录树。)
edits:元数据的操作日志(针对文件系统做的修改操作记录)
namenode内存中存储的是 =fsimage+edits。
NameNode详解
作用:
Namenode 起一个统领的作用,用户通过 namenode 来实现对其他数据的访问和操作,类似于 root 根目录的感觉。
Namenode 包含:目录与数据块之间的关系(靠 fsimage 和 edits 来实现),数据块和节点之间的关系
fsimage文件与 edits 文件是 Namenode 结点上的核心文件。
Namenode 中仅仅存储目录树信息,而关于 BLOCK 的位置信息则是从各个 Datanode 上传到 Namenode 上的。
Namenode 的 目录树信息就是物理的存储在 fsimage 这个文件中 的,当 Namenode 启动的时候会首先读取 fsimage 这个文件,将目录树信息装载到内存中。
而 edits 存储的是日志信息,在 Namenode 启动后 所有对目录结构的增加,删除,修改等操作都会记录到 edits 文件中,并不会同步的记录在 fsimage 中。
而当 Namenode 结点关闭的时候,也不会将 fsimage 与 edits 文件进行合并,这个合并的过程实际上是发生在 Namenode 启动的过程中。
也就是说,当 Namenode 启动的时候,首先装载 fsimage 文件,然后在应用 edits 文件,最后还会将最新的目录树信息更新到新的 fsimage 文件中,然后启用新的 edits 文件。
整个流程是没有问题的,但是有个小瑕疵,就是如果 Namenode 在启动后发生的改变过多,会导致 edits 文件变得非常大,大得程度与 Namenode 的更新频率有关系。
那么在下一次 Namenode 启动的过程中,读取了 fsimage 文件后,会应用这个无比大的 edits 文件,导致启动时间变长,并且不可控,可能需要启动几个小时也说不定。
Namenode 的 edits 文件过大的问题,也就是 SecondeNamenode 要解决的主要问题。
SecondNamenode 会按照一定规则被唤醒,然后进行 fsimage 文件与 edits 文件的合并,防止 edits 文件过大,导致 Namenode 启动时间过长。
DataNode详解
DataNode 在 HDFS 中真正存储数据。
首先解释块(block)的概念:
- DataNode 在存储数据的时候是按照 block 为单位读写数据的。block 是 hdfs 读写数据的基本单位。
- 假设文件大小是 100GB,从字节位置 0 开始,每 128MB 字节划分为一个 block,依此类推,可以划分出很多的 block。每个 block 就是 128MB 大小。
- block 本质上是一个 逻辑概念,意味着 block 里面不会真正的存储数据,只是划分文件的。
- block 里也会存副本,副本优点是安全,缺点是占空间
SecondaryNode
执行过程:从 NameNode 上 下载元数据信息(fsimage,edits),然后把二者合并,生成新的 fsimage,在本地保存,并将其推送到 NameNode,同时重置 NameNode 的 edits.
工作原理(转自“大牛笔记”的博客,由于实现是清晰,受益很大,在此不做改动)
写操作:
有一个文件 FileA,100M 大小。Client 将 FileA 写入到 HDFS 上。
HDFS 按默认配置。
HDFS 分布在三个机架上 Rack1,Rack2,Rack3。
a. Client 将 FileA 按 64M 分块。分成两块,block1 和 Block2;
b. Client 向 nameNode 发送写数据请求,如图蓝色虚线①——>。
c. NameNode 节点,记录 block 信息。并返回可用的 DataNode,如粉色虚线②———>。
Block1: host2,host1,host3
Block2: host7,host8,host4
原理:
NameNode 具有 RackAware 机架感知功能,这个可以配置。
若 client 为 DataNode 节点,那存储 block 时,规则为:副本 1,同 client 的节点上;副本 2,不同机架节点上;副本 3,同第二个副本机架的另一个节点上;其他副本随机挑选。
若 client 不为 DataNode 节点,那存储 block 时,规则为:副本 1,随机选择一个节点上;副本 2,不同副本 1,机架上;副本 3,同副本 2 相同的另一个节点上;其他副本随机挑选。
d. client 向 DataNode 发送 block1;发送过程是以流式写入。
流式写入过程,
1>将 64M 的 block1 按 64k 的 package 划分;
2>然后将第一个 package 发送给 host2;
3>host2 接收完后,将第一个 package 发送给 host1,同时 client 想 host2 发送第二个 package;
4>host1 接收完第一个 package 后,发送给 host3,同时接收 host2 发来的第二个 package。
5>以此类推,如图红线实线所示,直到将 block1 发送完毕。
6>host2,host1,host3 向 NameNode,host2 向 Client 发送通知,说“消息发送完了”。如图粉红颜色实线所示。
7>client 收到 host2 发来的消息后,向 namenode 发送消息,说我写完了。这样就真完成了。如图黄色粗实线
8>发送完 block1 后,再向 host7,host8,host4 发送 block2,如图蓝色实线所示。
9>发送完 block2 后,host7,host8,host4 向 NameNode,host7 向 Client 发送通知,如图浅绿色实线所示。
10>client 向 NameNode 发送消息,说我写完了,如图黄色粗实线。。。这样就完毕了。
分析,通过写过程,我们可以了解到:
①写 1T 文件,我们需要 3T 的存储,3T 的网络流量贷款。
②在执行读或写的过程中,NameNode 和 DataNode 通过 HeartBeat 进行保存通信,确定 DataNode 活着。如果发现 DataNode 死掉了,就将死掉的 DataNode 上的数据,放到其他节点去。读取时,要读其他节点去。
③挂掉一个节点,没关系,还有其他节点可以备份;甚至,挂掉某一个机架,也没关系;其他机架上,也有备份。
读操作:
读操作就简单一些了,如图所示,client 要从 datanode 上,读取 FileA。而 FileA 由 block1 和 block2 组成。
那么,读操作流程为:
a. client 向 namenode 发送读请求。
b. namenode 查看 Metadata 信息,返回 fileA 的 block 的位置。
block1:host2,host1,host3
block2:host7,host8,host4
c. block 的位置是有先后顺序的,先读 block1,再读 block2。而且 block1 去 host2 上读取;然后 block2,去 host7 上读取;
上面例子中,client 位于机架外,那么如果 client 位于机架内某个 DataNode 上,例如,client 是 host6。那么读取的时候,遵循的规律是:
优选读取本机架上的数据。
运算和存储在同一个服务器中,每一个服务器都可以是本地服务器
补充
元数据
元数据被定义为:描述数据的数据,对数据及信息资源的描述性信息。(类似于 Linux 中的 i 节点)
以“blk_”开头的文件就是 存储数据的 block。这里的命名是有规律的,除了 block 文件外,还有后 缀是“meta”的文件,这是 block 的源数据文件,存放一些元数据信息。
数据复制
NameNode 做出关于块复制的所有决定。它周期性地从集群中的每个 DataNode 接收到一个心跳和一个阻塞报告。收到心跳意味着 DataNode 正常运行。Blockreport 包含 DataNode 上所有块的列表。
使用 HDFS dfs 命令对文件进行增删改查操作 https://www.linuxidc.com/Linux/2018-08/153641.htm
Hadoop 集群间的 HDFS 文件拷贝 https://www.linuxidc.com/Linux/2017-09/146879.htm
: