Hadoop系列之HDFS初识、理论基础与读写流程

2020-06-26  本文已影响0人  l1fe1

1 HDFS初识

考虑这样一个问题:文件切成很多小文件块散列存储在集群中时,是如何知道每个小文件块存储的位置的呢?让我们举个例子来解释一下,假设现在有100台机器,如果有10个人拿着10批数据过来存储,那么他们可能会找到不同的人把他们的数据各自存储在不同的机器上,过了10天之后,这些人想要取回他们的数据,但是他们忘了自己的数据存储在谁那里了,那么这些数据就取不回来了。那么该如何解决这个问题呢?我们可以单独拿出一台机器用于记录,那么每当有人要存储数据的时候,都先找到这台机器,然后这台机器会告诉他将数据存储在哪,这个询问的过程是很快的,每个人问完之后就会拿着数据去存储,然后下一个人过来接着问...如果这个例子你能听懂,那么恭喜你,HDFS你已经学会了。上述的过程其实就是指的HDFS中的NameNode和DataNode各司其职的过程,DataNode用于存储数据,而NameNode用于存储文件的元数据描述信息。让我们来进一步思考一下,如果把上述例子中的文件数据换成一张一张的一百块钱,比如有个人过来要存100块钱,我说你去张三那存吧,这时候我应该立刻写下谁谁谁的100块钱存在张三那了吗?这是不可能的,因为有可能我记完之后这个人没去张三那存,如果我记下了这笔帐,那个人回来找我取回那100块钱,我让他去张三那,那张三就有苦说不出了,这就是所谓的数据一致性问题。数据的一致性问题一定是要非常小心的,尤其是在分布式、多节点多人协作的情况下。因此在上面的例子中,一定是要张三给我发送一个确认的回报之后,我才能把这个100块钱给记录下来的。HDFS就是这样一个用多个节点散列未来要存储的数据,然后用一个主节点进行记账的分布式文件系统。此外,记账这件事情,一个人可以做,两个人也可以做,但是两个人记账中面临的数据一致性问题会更加复杂(两个人之间同步信息),因此HDFS采用了一主的架构。

分布式文件系统那么多,为什么hadoop项目中还要开发一个hdfs文件系统?
我们知道,在hadoop项目里面除了hdfs文件系统模块之外,还有另外一个很重要的用于计算的模块,因此我们可以推测出,hdfs一定会具备一个特征:它能更好的支持分布式计算。

2 HDFS理论知识点

2.1 存储模型

无论是什么文件,在计算机中存储的都是二进制,二进制在计算机中就是一个个二进制位,但是在计算机中,一般很少用二进制位去描述文件,而是会用字节去描述,我们看到的文件大小一般都是用字节作为单位的,文件本质上都是字节数组。

2.2 架构设计

HDFS架构 块复制

Windows和Linux文件系统的差异。
Windows和Linux上都会有硬盘,而硬盘上都有分区,在windows上分区对应的是盘符(c盘、d盘),这个时候如果你想要存一些目录,需要自主去找一个分区,在分区下去存一级目录、二级目录,而linux中虽然也有两个分区,但是它的分区会挂载到它内存的虚拟目录树结构上,它是由一个虚拟的根起,根下的A目录可能是你的第一个分区,B目录可能是你的第二个分区。因此在你使用linux系统的时候,你好像感觉不到底层到底分了几个分区,而在使用windows的时候,容易混乱。比如说,如果你在windows中写了一个软件,这个软件必须从G盘加载一个文件(conf、xml),那么这个软件在其他人的电脑上面可能就跑不起来了,因为有的电脑上根本就没有G盘,而如果你使用的是linux系统,linux系统除了它的根目录结构之外,还有它的mount挂载(/g -> disk:G分区、/b -> disk:B分区),上述软件如果是在linux系统上面开发的,假如它的文件加载路径还是写死的,比如从/g目录下加载文件,这时候其他电脑可能也没有/g目录,但是这时它可以创建一个/g目录(可以挂载在不同的分区上,它的映射关系可以随便换),因此linux相对于windows来说使得软件具备了移动性。

2.3 角色功能

NameNode

角色即进程。
HDFS并没有真正存储数据,只是管理映射。

2.4 元数据持久化

数据持久化方式

  • 日志文件(文本文件):记录(append)实时发生的增删改操作(mkdir /abc),通过读取日志文件重放每一行指令来恢复数据
    优点:完整性比较好
    缺点:加载恢复数据慢、占空间
  • 镜像、快照、dump、db(二进制文件):间隔的(小时,天,10分钟,1分钟,5秒钟),内存全量数据基于某一时间点做的向磁盘的溢写
    优点:恢复速度快过日志文件
    缺点:因为是间隔的,容易丢失一部分数据

HDFS:

  • EditsLog:日志文件
    体积小,记录少:必然有优势
  • FsImage:镜像、快照
    如果能更快的滚动更新时点,必然有优势

HDFS采用的是最近时点的FsImage + 增量的EditsLog的持久化方案。
比如现在10点,HDFS中记录了9点的FsImage + 9点到10点的增量的EditsLog,那么通过以下步骤就能得到关机前的全量数据:

  1. 加载FsImage
  2. 加载EditsLog

FsImage时点是怎么滚动更新的?

  • 由NameNode8点溢写一次,9点溢写一次(每一小时溢写一次,产生大量I/O,耗费资源)
  • NameNode第一次开机的时候只写一次FsImage(假设8点),到9点的时候,EditsLog记录的是8~9点的日志,只需要将8~9点的日志的记录,更新到8点的FsImage中(使用另外一台机器:Secondary NameNode来做合并),FsImage的数据时点就变成了9点。

2.5 安全模式

  1. NameNode启动后会进入一个称为安全模式的特殊状态。
  2. 处于安全模式的NameNode是不会进行数据块的复制的。
  3. NameNode从所有的 DatNnode接收心跳信号和块状态报告。
  4. 每当NameNode检测确认某个数据块的副本数目达到这个最小值,那么该数据块就会被认为是副本安全(safely replicated)的。
  5. 在一定百分比(这个参数可配置)的数据块被NameNode检测确认是安全之后(加上一个额外的30秒等待时间),NameNode将退出安全模式状态。
  6. 接下来它会确定还有哪些数据块的副本没有达到指定数目,并将这些数据块复制到其他DataNode上。

NameNode存的元数据主要有两种:文件属性、每个块存在哪个DataNode上。
在持久化的时候,文件属性会持久化,但是文件的每一个块不会持久化。恢复的时候,NameNode会丢失块的位置信息。
那么为什么NameNode不持久化块的位置信息呢?
这就又回到了分布式时代数据一致性的问题了,假如NameNode持久化了块的位置信息,但是由于集群启动时DataNode挂掉了,那么这些块就取不回来了,这就会产生数据不一致的问题,因此NameNode宁可不存块的位置信息,而是等DataNode和NameNode建立心跳,然后向它汇报块的信息,这个过程就叫安全模式。

2.6 HDFS中的SNN

Secondary NameNode(SNN)

SNN存在的意义就是让EditsLog很小、恢复很快。

SNN合并过程

2.7 Block的副本放置策略

在早期的HDFS中,第一个副本和第二个副本会放在同机架,第三个副本才会出机架,这样当副本数设定为2的时候,如果副本所在机架挂了,会导致这个块丢失,因此在2.x的时候修正了这个问题,第二个副本放在与第一个副本不同的机架上。
第二个副本和第三个副本放在同一机架是为了减少跨交换机的成本。

数据中心

2.8 HDFS读写流程

2.8.1 HDFS写流程
HDFS写流程

Client在与NameNode进行交互的时候,会触发副本放置策略,NameNode会根据副本放置策略,在返回DataNode信息时做一个排序(根据距离),Client本机上的DataNode会排在第一位。然后Client会和第一个DataNode建立tcp连接,第一个DataNode和第二个DataNode建立tcp连接,第二个DataNode和第三个DataNode建立tcp连接,这些连接链路被称为pipline。

DataNode如果挂掉会怎么办?

DataNode会向NameNode汇报状态,因此在1个DataNode挂掉之后,由于汇报时的DataNode少了一个,这时NameNode会让某个DataNode从自身再复制一个DataNode出来。

2.8.2 HDFS读流程
HDFS读流程
上一篇下一篇

猜你喜欢

热点阅读