`
朝着梦想
  • 浏览: 2711 次
  • 性别: Icon_minigender_2
  • 来自: 长沙
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

云计算之初感悟

    博客分类:
  • java
 
阅读更多

     以前听别人说起云计算的时候,总觉得它是一个高大上的一个东西,因为自己不知道,会觉得它会很难吧。但这几天自己自己静下心来,看了一些相关方面的书后,发现它没有想象中的那么深奥,只是时代发展的产物罢了,是随着互联网的发展产生的大数据应运而生的一种东西。

     Hadoop系统可以高效的存储、管理、分析海量数据,Hadoop的核心是MapReduce和HDFS,先谈一下HDFS的基本架构吧,HDFS采用主从文件架构对文件系统进行管理。一个HDFS集群是由一个NameNode和一定数目的DataNode组成的。默认HDFS数据块大小是64MB,HDFS上的文件也进行分块,块是HDFS的文件存储处理的单元。和普通文件系统不同的是,HDFS中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间。NameNode是一个中心服务器,负责管理文件系统的名字空间以及客户端对文件的访问。集群中的DataNode一般是一个节点运行一个DataNode进程,负责管理他所在节点上的存储。HDFS展示了文件系统的名字空间,用户能够以文件的形式在上面存储数据。从内部看,一个文件其实被分成一个或多个数据块,这些块存储在一组DataNode上。DataNode执行文件系统的名字空间模块,比如打开、关闭、重命名文件或目录。它也负责数据块到具体DataNode节点的映射。DataNode负责处理文件系统客户端的读/写请求,在NameNode的统一调度下进行数据块的创建、删除和复制。

    下面说一下HDFS中的读和写文件流程,先说一下读文件的流程:

 

 

如上图所示:

         1、客户端(client)用FileSystem的open()函数打开文件,对应于具体的HDFS文件系统,DFS创建输入流FSDataInputStream返回给客户端,客户端使用这个输入流读取数据;

          2、DFS用RPC调用NamNode节点,得到文件的数据块的地址,对于每一个数据块,Namenodf返回保存数据块的数据节点的地址;

          3、客户端调用FSDataInputStream.read()方法读取文件数据时,DFSInputStream对象通过和DataNode间的“读数据“接口,和最近的DataNode建立联系,客户端反复调用read()方法,数据会通过DataNode和客户端连接上的数据包返回客户端。当到达块的末端时,DFSInputStream会关闭和数据节点间的连接,并通过远程调用getBlockLocations()方法得到下一个数据块的DataNode信息,再读取数据;

          4、由于客户端的getBlockLocation()不会一次返回文件的所有的数据块的信息,DFSInpuStream可能需要多次使用该远程方法,检索下一组数据块的位置信息,对于客户端来说,他读取的是一个连续的数据流,当客户端完成读取任务时,通过close()方法关闭输入流。

 

然后介绍一下客户端写文件的过程:



 

如上图所示:

        1、客户端调用DFS的create()方法创建文件,这是DFS创建DFSOutputStream,并由远程过程调用,让NamdNode执行同名方法,在文件系统的命名空间中创建一个新文件。DataNode创建一个新文件后,并将记录创建操作到编辑日志edits,远程方法调用结束后,DFS将DFSOutputStream对象包裹到FSDataOuputStream实例中,返回给客户端;(如图1,2)

        2、客户端写入文件时,由于create()方法调用创建了一个空文件,所以,DFSOutputStream实例首先需要向NameNode申请数据块,addBlock()方法成功执行后,返回一个LocatedBlock对象,该对象包含了新数据块的数据块标示和版本号。

        3、通过上述信息,DFSOutputStream就可以和DataNode联系,通过写数据接口建立数据流管道。客户端写入FSDataOutputStream流中的数据,被打包成一个一个的文件包,放入DFSOutputStream对象的内部队列,该队列中的文件包最终被打包成数据包,发往数据流管道,流经数据流管道上的各个DataNode,并持久化。确认包逆流而上,从数据流管道依次次发往客户端,客户端收到应答时,他将对应的包内部队列移除。

        4、DFSOutputStream在写完一个数据块时,数据流管道上的节点,会通过和NamdNode的远程接口的blockReceived()方法,向DataNode提交数据块,如果数据队列中还有等待输出的数据,DFSInputStream对象再次调用addBlock()方法,为文件添加新的数据块。

       5、客户端完成数据的写入后,调用close方法关闭流,关闭意味着客户端不会再往流中写入数据,所以,当DFSOutputStream数据队列中的文件包都收到应答后,就可以使用客户端的ClientProtocol.complete()方法通知NameNode关闭文件,完成一次正常的写文件流程;

    

     从上述文件的读写过程可以看出,客户端读写数据是直接和DataNode建立数据流管道来读写数据的,而NameNode是用来管理DataNode的。

    

 

      理解了HDFS的基本架构后,下面来谈一下MapRedude:

    

 如图所示:在Hadoop中,每个MapReduce任务都被初始化为一个Job,每个Job又可以分为两种阶段:map阶段和reduce阶段。这两个阶段分别用两个函数表示,即map函数和reduce函数。map函数接收一个<key,value>形式的输入,然后同样产生一个<key,value>形式的中间输出,Hadoop函数接收一个如<key,(list of values)>形式的输入,然后对这个value集合进行处理,每个reduce产生0或1个输出,reduce的输出也是<key,value>形式的。其实map的过程就是一个一个统计的过程,而reduce的过程则是对map统计的结果进行再统计的过程,即是对每一个key出现的次数进行统计的过程,即将相同的统计在一起。实例中如果我们要统计论文引用的次数的话,需要遍历论文,一一计数,因为文章数量很多,需要进行很多次内外存交换,这无疑会延长程序的执行时间,用MapReduce会高效率的解决这个问题。

   其实这些框架,只有我们真正地用在实例中,才会理解地更深入,期待进一步的发现。

 

 

  • 大小: 45.2 KB
  • 大小: 47.4 KB
  • 大小: 34.7 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics