代码改变世界

Hadoop的核心--HDFS

2016-04-05 22:40  一个爱学习的小码农  阅读(517)  评论(0)    收藏  举报

   Hadoop的核心就是HDFS和MapReduce,而两者只是理论基础,不是具体可使用的高级应用,Hadoop旗下有很多经典子项目,比如HBase、Hive等,这些都是基于HDFS和MapReduce发展出来的。要想了解Hadoop,就必须知道HDFS和MapReduce是什么。

1.概要

  HDFS(Hadoop Distributed File System,Hadoop分布式文件系统),它是一个高度容错性的系统,适合部署在廉价的机器上。HDFS能提供高吞吐量的数据访问,适合那些有着超大数据集(large data set)的应用程序

  数据块(block):大文件会被分割成多个block进行存储,block大小默认为64MB。每一个block会在多个datanode上存储多份副本,默认是3份。

  namenode:namenode负责管理文件目录、文件和block的对应关系以及block和datanode的对应关系。

  datanode:datanode就负责存储了,当然大部分容错机制都是在datanode上实现的

2.设计特点

  1、大数据文件,非常适合上T级别的大文件或者一堆大数据文件的存储,如果文件只有几个G甚至更小就没啥意思了。

  2、文件分块存储,HDFS会将一个完整的大文件平均分块存储到不同计算器上,它的意义在于读取文件时可以同时从多个主机取不同区块的文件,多主机读取比单主机读取效率要高得多得都。

  3、流式数据访问,一次写入多次读写,这种模式跟传统文件不同,它不支持动态改变文件内容,而是要求让文件一次写入就不做变化,要变化也只能在文件末添加内容。

  4、廉价硬件,HDFS可以应用在普通PC机上,这种机制能够让给一些公司用几十台廉价的计算机就可以撑起一个大数据集群。

  5、硬件故障,HDFS认为所有计算机都可能会出问题,为了防止某个主机失效读取不到该主机的块文件,它将同一个文件块副本分配到其它某几个主机上,如果其中一台主机失效,可以迅速找另一块副本取文件。

3、数据流

  1)读文件的过程

  * 客户端(client)用FileSystem的open()函数打开文件
    * DistributedFileSystem用RPC调用元数据节点,得到文件的数据块信息。
    * 对于每一个数据块,元数据节点返回保存数据块的数据节点的地址。
    * DistributedFileSystem返回FSDataInputStream给客户端,用来读取数据。
    * 客户端调用stream的read()函数开始读取数据。
    * DFSInputStream连接保存此文件第一个数据块的最近的数据节点。
    * Data从数据节点读到客户端(client)
    * 当此数据块读取完毕时,DFSInputStream关闭和此数据节点的连接,然后连接此文件下一个数据块的最近的数据节点。
    * 当客户端读取完毕数据的时候,调用FSDataInputStream的close函数。
    * 在读取数据的过程中,如果客户端在与数据节点通信出现错误,则尝试连接包含此数据块的下一个数据节点。
    * 失败的数据节点将被记录,以后不再连接。

                

  2)写文件的过程

  * 客户端调用create()来创建文件
    * DistributedFileSystem用RPC调用元数据节点,在文件系统的命名空间中创建一个新的文件。
    * 元数据节点首先确定文件原来不存在,并且客户端有创建文件的权限,然后创建新文件。
    * DistributedFileSystem返回DFSOutputStream,客户端用于写数据。
    * 客户端开始写入数据,DFSOutputStream将数据分成块,写入data queue。
    * Data queue由Data Streamer读取,并通知元数据节点分配数据节点,用来存储数据块(每块默认复制3块)。分配的数据节点放在一个pipeline里。
    * Data Streamer将数据块写入pipeline中的第一个数据节点。第一个数据节点将数据块发送给第二个数据节点。第二个数据节点将数据发送给第三个数据节点。
    * DFSOutputStream为发出去的数据块保存了ack queue,等待pipeline中的数据节点告知数据已经写入成功。
    * 如果数据节点在写入的过程中失败:
        * 关闭pipeline,将ack queue中的数据块放入data queue的开始。
        * 当前的数据块在已经写入的数据节点中被元数据节点赋予新的标示,则错误节点重启后能够察觉其数据块是过时的,会被删除。
        * 失败的数据节点从pipeline中移除,另外的数据块则写入pipeline中的另外两个数据节点。
        * 元数据节点则被通知此数据块是复制块数不足,将来会再创建第三份备份。
        * 当客户端结束写入数据,则调用stream的close函数。此操作将所有的数据块写入pipeline中的数据节点,并等待ack queue返回成功。最后通知元数据节点写入完毕。