文章目录
一、HDFS 的产生背景及定义
1.1 产生背景
我们知道随着数据量越来越大一台机器的性能难以处理,所以需要多台机器合作,那么同时就需要有一个管理多台机器上文件的文件系统,这就产生了分布式文件系统,hdfs 只是其中的一种。
1.2 定义
HDFS(Hadoop Distribute File System) 是一个文件系统,用于存储文件,通过目录树来定位文件;其次,它是分布式的,有很多服务器联合起来实现其功能,集群中的服务器有各自的角色。
HDFS 的适用场景:适合一次写入,多次读出的场景,且不支持文件的随机修改。适合用来左数据分析,并不适合用来做网盘应用。
二、HDFS 优缺点
2.1 优点
-
高容错性,数据自动保存多个副本,默认是三个,如果在某台节点的数据丢失,它会自动从其它节点复制副本。
-
适合处理大数据,
(1)数据规模大:能够处理数据达到 TB 甚至 PB
(2)文件规模大:能够处理百万规模以上的文件数量
-
可构建在廉价的机器上,通过多副本机制,提高可靠性
2.2 缺点
-
不适合低时延数据的访问
-
不适合存储大量小文件
(1)如果存储大量小文件,它会占用 NameNode 大量内存来存储文件的元数据信息和块信息,在 NameNode 中,不管文件的大小,元数据信息所占的大小都是固定的,注意:文件在磁盘中的存储所占空间与块大小无关,比如文件大小为 1 M,而块大小是 128M,那么文件在磁盘中只占用 1 M 的空间。
(2)小文件存储的寻址时间会超过读取时间,这违反了 hdfs 的设计目标(寻址时间为传输时间的 1%)
-
不支持并发写入、随机修改
三、HDFS 架构
作为一个文件系统,主要就是要读写,所以 hdfs 架构中主要工作的有三个角色,还有一个辅助角色(但非常重要)
NameNode:
(1)负责管理 hdfs 的名称空间,即存储元数据信息(文件名、大小、位置等)
(2)配置副本策略
(3)接收来自 DN 的心跳,并且可以给 DN 发送命令
(4)接收 DN 上报的块信息
(4)处理客户端请求
DataNode:
(1)存储实际的数据块(注意,不是文件本身)
(2)执行数据块的读写操作
Client:
(1)把文件分成块,上传到 hdfs
(2)与 NN 交互发出读写文件的请求,并获得文件的位置信息
(3)与 DN 交互,读写文件
SecondaryNameNode:
(1)辅助 NN,分担其工作量,比如定期合并 Fsimage 和 Edits,然后推送给 NN(注意:合并 Fsimage 和 Edits 十分占内存, 2NN 与 NN 不能放在同一台节点上,否则会降低 NN 的性能,第四部分详解)
(2)在紧急情况下,辅助恢复 NN
四、HDFS 块(Block)
块是 hdfs 中存储、读写数据的基本单位。
上面提到了客户端向 DN 读写数据的时候,是按块来读写的,那么块如何划分呢。
HDFS 的设计目标是寻址时间占传输时间的 1%,一般情况下,寻址时间为 10ms(?),那么传输时间就是 1000 ms 即 1s,现在大多数磁盘的读写速度是 100 MB/s,那么传输一个单位的数据就是 1s × 100 MB/s = 100 MB,而 100 接近 128(2的7次方),所以 hdfs 默认的块大小是 128 MB。
当然,我也说是大多数磁盘的读写速度是 100 MB/s,而有些性能好的磁盘可以达到更高的速度,那么就可以把块设置的更大。
块要结合到磁盘读写速度,既不能太大,也不能太小,否则都会违反 hdfs 的设计目标:
(1)太大会导致寻址时间变的特小,而传输时间变的特大。程序在处理这块数据时,会非常慢。
(2)太小会导致 NN 中存储的块信息太多,增加 NN 的寻址时间。
综上:影响 hdfs 块大小的就是磁盘的读写速度。当然也不能让寻址时间过长,这就要求我们不能在 hdfs 中存储大量的小文件。
五、HDFS 读写数据流程
5.1 写数据的流程
1、Client 向 NN 发出写文件 a.txt 请求
2、NN 查看是否已经存在 a.txt,如果不存在通知 Client 可以写
3、Client 写向 NN 请求写 block
4、NN 查找可用的 DN(就近原则),返回 DN1,DN2,DN3
5、Client 向 DN1 发出建立写数据的通道,接着 DN 之间建立通道
6、DN 建立通道成功后返回 ack 给 Client
7、Client 向 DN1 写入数据,DN1 向其它 DN 复制数据
8、Client 通知 NN 自己写完了第一个 Block
(注意:写入是并行的)
5.2 读数据的流程
1、客户端向 NN 发出读文件请求
2、NN 查看元数据信息,返回该文件对应的 block 所在的 DN
3、客户端挑选一台 DN(就近原则,然后随机)服务器,请求读数据
4、DN 向客户端传数据
注意:hdfs 读数据不是并发的,而是读完一个块再读一个块的
5.2 网络拓扑——节点距离计算
上面在提到读写数据的时候都有一个就近原则,因为就近的网络传输时延小,那么 hdfs 是怎么判断节点距离的呢。
节点距离:两个节点到达最近的共同祖先的距离总和。
举例:计算节点 9 和 节点 5 的距离:
共同祖先是节点 8,节点5 到 节点8 的距离为 3,节点 9 到节点 8 的距离为 1,所以它两的距离就是 3 + 1 = 4
5.2 副本策略
第一个副本在 Client 所在的节点上,如果客户端在集群外,随机选一个。
第二个副本在与第一个副本所在同一机架的不同节点上。
第三个副本在不同机架上。
四、NameNode 与 SecondaryNameNode 工作机制
4.1 引入
首先,我们知道,NN 把元数据信息存在了内存里,因为需要随机访问,如果存在磁盘里,性能必然太低,但是存在内存里就又有一个问题——如果 NN 宕机,那么这些数据都会丢失,为了解决数据丢失的问题,NN 中维护了一个 fsimage,它用来备份元数据信息然后存到磁盘。
但因为 fsimage 是元数据的备份,所以它为了同步元数据肯定要平凡地对磁盘进行随机写操作,这又会导致效率变低;所以 NN 又引入了一个 Edits,它只用来记录 hdfs 的操作,不存实际数据,当 NN 宕机时,可以通过合并 fsimage 来恢复之前的数据,因为 Edits 在磁盘中只需要进行追加数据即可,免去了磁盘寻址的时间,速度就会很快。(感觉 Edits 和 spark 的 RDD 很像,都是记录操作)
这时,又有一个问题,如果 NN 运行了很久,那么 Edits 中会有大量的操作信息,等到 NN 宕机重启后,Edits 和 fsimage 进行合并所需的时间就会特别长,所以 Edits 需要和 fsimage 定期地合并,但是,这个合并的工作也十分占内存,如果在 NN 上进行,就会大幅度降低 NN 的性能,所以这个合并的工作需要一个新的节点来完成,我们称之为 ————Secondary NameNode
4.2 工作流程详解
NameNode:
1、NN 启动,合并 Edits 和 Fsimage 将元数据信息存储到内存中
2、客户端对元数据进行增删改请求
3、NN 把请求的操作记录到 edits 中,NN 滚动 Edits 形成一个新的 edits_inprogress(假设需要检查点),把操作写入 Edits_inprogress;要是不需要检查点的话就继续往原来的 edits中写就可以了,这时 2NN 不会进行操作。
4、NN 处理客户端请求
Secondary NameNode:
1、2NN 询问 NN 是否需要检查点(Edits 满了或者检查时间到了)
2、如果需要执行检查点,2NN 把 NN 中的 edits 和 fsimage 拷贝过来(这时 NN 会生成一个新的 edits,把检查点之后的客户端请求都记录到新的 edits 中)
3、2NN 把拷贝过来的 edits 和 fsimage 加载到内存合并,生成新的 fsimage 返回给 NN
4、NN 用新的 fsimage 覆盖旧的。
五、DataNode 工作机制
1、DN 启动,向 NN 注册
2、NN 返回注册成功
3、DN 周期性的向 NN 上报自己所有的块信息
4、DN 每三秒发送心跳给 NN 让 NN 知道自己还活着,并且带回 NN 的操作命令
5、如果 NN 10分钟没有收到某个 NN 的心跳,则认为该节点已挂掉