Hadoop学习之路 --- HDFS(分布式文件系统)

Hadoop自带一个称为HDFS的分布式文件系统,即Hadoop Distributed Filesystem,HDFS是以流式数据访问模式来存储超大文件,运行于商用硬件集群上。

                                                                                                                                                              ----<<Hadoop权威指南>>

名词解释:

  • 什么是HDFS:

一个用于分布式环境下的文件系统,与正常文件系统不同的是,它会让集群中的每个机器仿佛访问同一个文件系统,即在A机器写入HDFS的文件,在B机器也能看到,在B机器删除HDFS文件,集群其他机器中的该文件也会被删除。

  • 什么是流式数据访问:

流式数据,特点就是,像流水一样,不是一次过来而是一点一点“流”过来。而你处理流式数据也是一点一点处理。如果是全部收到数据以后再处理,那么延迟会很大,而且在很多场合会消耗大量内存。

 

  • 什么是商用硬件:

在零售店就能买到的一般硬件,及一般企业可简单获取到的硬件,HDFS可以运行与商业硬件上,说明对硬件要求不高 ,具有普及性。

 

  • 什么是元数据:

元数据是关于数据的组织、数据域及其关系的信息,简言之,元数据就是关于数据的数据

 

  • 什么是HDFS数据块:

每个磁盘有默认的数据块,这是磁盘读写的最小单位。文件系统的块大小一般为磁盘块的整数倍。磁盘块大小一般为 512 字节。

HDFS 文件系统也有块(block)的概念,默认值为 128M,也可以修改。超过块大小的文件在存储的时候会被分为多个分块(chunk)。

有点需要注意:HDFS 中小于一个块大小的文件不会占据整个块的空间,而单一磁盘中如果文件小于块大小,那么整个磁盘块的空间都会被占用。

(简单来说,如果分出来的块大小小于128M,不小于512字节的内容,则占据它对应的大小的磁盘空间,而如果大小小于512字节的内容,则占据512字节大小的磁盘空间,不是很准确,大概这个意思)

 

首先是HDFS的几个比较大的特点:

1.超大文件:

HDFS适合存储,读取超大的文件,它会将文件分为一个个的数据块,并分别存放在集群上的不同机器中,并进行备份以确保数据安全性,即通过使用多个硬件资源的方式实现超大文件的安全存储。

 

2.流式访问:

HDFS的设计建立在更多地响应"一次写入、多次读写"任务的基础上。也就是说,我们大部分的时间是花在一次生成数据集后,对数据集的各种分析计算上的,每次分析都将设计该数据集的大部分数据甚至全部数据,因此读取整个数据集的时间延迟比读取某一条记录的时间延迟更重要。

 

3.商用硬件:

HDFS可以运行与商业硬件上,说明对硬件要求不高 ,具有普及性,但是相应的使用的硬件廉价也就代表其故障率会比较高,在大型集群中,节点的故障不可不靠考虑,在设计上,HDFS被设计成当节点故障时,能继续运行且不让用户感觉到明显的中断。

 

4.高数据吞吐量(不适合低延迟数据访问):

HDFS的设计主要是为了超大文件的存储访问处理,在提高数据吞吐量的同时,难免牺牲了相当的数据访问耗时,所以如果需要低延迟的数据访问,HDFS可能就不是很适合了。

5.不适合存储大量小文件:

HDFS中有namenode节点,也叫元数据节点,它会存储在 HDFS 文件系统上的数据的元数据,(比如文件系统树及整棵树内所有的文件和目录,每个文件中各个数据块所在数据节点信息,但并不永久保存块的位置信息,因为这块可能随时变化。这部分的信息在系统启动的时候根据数据节点的信息重建。)namenode将这些元数据存储在内存中,所以如果出现存储大量小文件,就会导致namenode中的元数据过大,超出硬件能力。

 

6.不支持多用户写入及任意修改文件:

在HDFS的一个文件中只有一个写入者,而且写操作只能在文件末尾完成,即只能执行追加操作。

 

 

HDFS的组成:

HDFS由两类节点组成,一类是管理节点(namenode),一类是工作节点(datanode)

 

namenode:

namenode 维护 HDFS 文件系统的元数据。管理文件系统及其命名空间,维持整个文件系统树,及整棵树内的所有文件,目录,这些信息以文件形式永久化存储在本地磁盘上:命名空间镜像文件,编辑日志文件,同时为了防止日志越来越大,会周期性将元数据节点的命名空间镜像文件和修改日志合并。同时它也记录着每个文件中各个块所在节点的信息(哪个块在哪个datanode上),但这个信息并不是永久保存,因为这块可能随时变化,而是在每次系统重启时根基数据节点信息重建。如果没有 namenode,文件系统将无法工作,由于文件的元数据都存储在 namenode,如果 namenode 的数据损坏,那么存储在 datanode 上的数据就作废了。

 

datanode:

datanode 是 HDFS 文件系统存储具体数据的节点。它们根据 namenode 节点的调度来存储和检索文件的数据块,并将存储的块的列表定期发送给 NameNode 管理节点。

 

简单来说,即namenode是保存元数据的,datanode是文件系统中真正存储数据的地方。

一般来说,一个集群上会运行多个datanode与一个namenode,可以将datanode当成真正打仗的小兵,namenode当成不亲自动手,而是给小兵发出各种命令的指挥官,小兵可以有很多个,但指挥官只能有一个,不然命令各发各的,岂不是乱套了,而在容错方面,datanode挂了,即小兵死了还有其他小兵,那么namenode挂了,即指挥官死了呢?呢么就由副手担任指挥官,代替其发号施令,即备用namenode开始活动。所以集群中,可以存在多个namenode,但同一时间只能有一个namenode处于activity(活动)状态。

 

 

HDFS的读写流程:

 

引用至https://blog.xiaoxiaomo.com/2016/06/26/Hadoop-HDFS%E4%B9%8B%E8%AF%BB%E5%86%99%E6%B5%81%E7%A8%8B/

 

  • 写入文件

DataNode的写操作流程 可以分为两部分:

  1. 准备工作,包括与NameNode的通信等;
  2. 真正的写操作。

 

 

    准备工作

 Hadoop学习之路 --- HDFS(分布式文件系统)

 

  1. HDFS client先会去询问NameNode,看哪些DataNode可以存储文件。文件的拆分是在HDFS client中完成的,比如拆分成A、B、C。
  2. NameNode查看它的元数据信息,发现DataNode 1,2,7上有空间可以存储Block A,于是将此信息告诉HDFS Client。
  3. HDFS Client接到NameNode返回的DataNode列表信息后,它会直接联系第一个DataNode1,让它准备好接收Block A(建立TCP连接)。
  4. 在DataNode1建立好TCP连接后它会把HDFS Client要写Block A的请求顺序传给DataNode2(在与HDFS Client建立好TCP连接后从HDFS Client获得的DataNodeli信息),同理传递给DataNode7。
  5. 当DataNode7准备好后,会回传信息过来,HDFS Client接到信息后表示都准备好了,就可以写数据了。

 

 

写入数据

Hadoop学习之路 --- HDFS(分布式文件系统) 

 

  1. HDFS Client开始往DataNode1写入Block A数据。同准备工作一样,当DataNode1接收完Block A数据后,它会顺序将Block A数据传输给DataNode2,然后DataNode2再传输给DataNode7。
  2. 每个DataNode在接收完Block A数据后,会发消息给NameNode,告诉它Block数据已经接收完毕。
  3. NameNode同时会根据它接收到的消息更新它保存的文件系统元数据信息。
  4. 当Block A 成功写入3个DataNode之后,DataNode1会发送一个成功信息给HDFS Client,同时HDFS Client也会发一个Block A成功写入的信息给NameNode。之后,HDFS Client才能开始继续处理下一个Block-Block B。

 

 

  • 读取文件

Hadoop学习之路 --- HDFS(分布式文件系统) 

 

 

  1. HDFS Client会先去联系NameNode,询问file.txt总共分为几个Block而且这些Block分别存放在哪些DataNode上。
  2. 由于每个Block都会存在几个副本,所以NameNode会把file.txt文件组成的Block所对应的所有DataNode列表都返回给HDFS Client。
  3. 然后HDFS Client会选择DataNode列表里的第一个DataNode去读取对应的Block。比如由于Block A存储在DataNode1,2,7,那么HDFS Client会到DataNode1去读取Block A;Block C存储在DataNode,7,8,9,那么HDFS Client就回到DataNode7去读取Block C。

 

HDFS的存储读取备份原则:

为了减少数据传输时的时间消耗,HDFS会优先吧数据存储,备份在相对较“近”的机器 上,读取的时候也是,优先读取距离较“近”的机器上的数据。

 

HDFS会尽可能维持集群上有设置备份数量的数据,假如现在有4个datanode节点 ,有一个文件被分为3个HDFS块,分别为A块,B块,C块,三个块加起来就是一个完整的数据,现在备份数量假如为3,呢么集群中就会有3份完整数据,即有3个A块,3个B块,3个C块,现在假设其分布是这样的:

Hadoop学习之路 --- HDFS(分布式文件系统)

 

 

当datanode3因为各种原因挂了之后,HDFS会在datanode4上拷贝A,B,以保证集群中有3份完整数据。

Hadoop学习之路 --- HDFS(分布式文件系统)

但是,因为在一个datanode里存储相同的块是没有作用的,所以如果这时候再挂一台datanode,呢么就不会再拷贝一份了,因为没有空的datanode可以给它拷贝,这里只是一个例子,具体情况会随着机器数量,HDFS设置等变化而有所不同。

 

HDFS小识记:

  • 每个datanode上只能存放一个副本
  • 一切读写的操作必须经过NameNode,但是传输数据本身不经过NameNode
  • 一般情况下,HDFS会存储设定副本数量的完整数据,即存储副本数量*完整数据分出来的HDFS块等于集群中该数据块的总数,但其存放的datanode,只能确定在副本数——数据块总数之间,无法在分配前确定有多少datanode会存放其数据块