Hadoop_HDFS文件读写代码流程解析和副本存放机制

Hadoop学习笔记总结node

01.RPC(远程过程调用)

1. RPC概念

远程过程指的不是同一个进程的调用。它是一种经过网络从远程计算机程序上请求服务,而不须要了解底层网络技术的协议。
不能直接拿到远程机器的服务实例:好比loginController拿不到另外一台主机loginService的实例,须要远程调用。一种实现:如Soap(http+xml)网络

  1. RPC至少有两个过程。调用方(client),被调用方(server)。
  2. client主动发起请求,调用指定ip和port的server中的方法,把调用结果返回给client。
  3. 客户端调用服务端的方法,意味着调用服务端的对象中的方法。
  4. 若是服务端的对象容许客户端调用,那么这个对象必须实现接口。
  5. 若是客户端可以调用到服务端对象的方法,那么这些方法必定位于对象的接口中。
  6. RPC是hadoop构建的基础。

2. 在Hadoop上的应用例子

NameNode和DataNode之间通讯,进程间的远程调用。并发

  1. 客户端获取NameNode的文件信息。(如客户端获取元数据信息,就是客户端经过RPC得到代理对象,调用NameNode的方法)
  2. 客户端写副本到DataNode,只写一个,其他的副本都是NameNode告诉DataNode去复制。
  3. DataNode和NameNode之间的心跳机制;DataNode按期汇报给NameNode自身的block信息(主要是当某个block损坏时,NameNode须要在元数据中更新副本信息)

hadoop和hbase中的大部分服务都是经过hadoop.ipc.RPC这个类来实现的。hadoop.ipc.RPC类中有两个重要的函数RPC.Builder和getProxy。RPC.Builder经过接口协议实现的实体来获取真正的server,getProxy获取远程访问的本地代理。框架

02.FileSystem数据流

1. 剖析文件读取

从HDFS读取到本地代码函数

Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://master:9000/");
FileSystem fs = FileSystem.get(conf);
FSDataInputStream is = fs.open(new Path(……));
FileOutputStream os = new FileInputStream("D:/test.txt");

FileSystem.get()方法oop

  1. FileSystem.get(conf)获取文件对象的实例对象。经过配置文件的conf信息判断,返回一个DistributedFileSystem的class,再经过反射DistributedFileSystem的实例并返回。
  2. DistributedFileSystem中有一个成员DFSClient,这个成员在初始化时,就是初始化本身的ClientProtocal代理对象(名称就是namenode),ClientProtocal是使用RPC框架和NN通讯的客户端代理对象。

FileSystem.open(path)过程
学习

  1. 首先调用FileSystem对象的open方法,其实DistributedFileSystem实例的DFSClient成员在调用open().
  2. DistributedFileSystem经过rpc(上述:DFSClient中的namenode代理)得到文件的第一批个block的locations,同一block按照重复数会返回多个locations,这些locations按照hadoop拓扑结构排序,距离客户端近的排在前面.
  3. fs.open()方法,返回文件系统输入流FSDataInputStream,该对象会被封装成DFSInputStream对象,这个类管理着DataNode和NameNode的I/O。客户端调用read方法,DFSInputStream最会找出离客户端最近的datanode并链接。
  4. 数据从datanode源源不断的流向客户端。
  5. 若是第一块的数据读完了,就会关闭指向第一块的datanode链接,接着读取下一块。这些操做对客户端来讲是透明的,客户端的角度看来只是读一个持续不断的流。
  6. 若是第一批block都读完了,DFSInputStream就会去namenode拿下一批blocks的location,而后继续读,若是全部的块都读完,这时就会关闭掉全部的流。

如下是代码实现过程

Ps:客户端直接链接datanode来读取数据,namenode来负责为每个block提供最优的datanode,namenode仅仅处理block location的请求,这些元数据都加载在namenode的内存中,hdfs经过datanode集群能够承受大量客户端的并发访问。ui

2. 剖析文件写入

步骤
新建一个文件,把数据从客户端写入,最后关闭文件。.net

  1. 过程和读取相似,经过FileSystem的实例对象DistributedFileSystem.create()返回FSDataOutputStream,其中的ClientProtocal代理对象就是对NameNode的RPC调用.
  2. 在文件系统命名空间建立一个文件,NameNode经过各项检查确保这个文件不存在和客户端建立权限。和以前类似,FSDataOutputStream封装着一个DFSOutputStream,负责DataNode和NameNode的通讯。
  3. DFSOutputStream会将数据分红一个个数据包,写入内部队列,DataStream处理数据队列,它的责任是根据DataNode列表来要求NameNode分配合适的新块来存储数据副本。dataStream将数据包流式传输到一个DataNode中,这个DataNode会传输到别的DataNode中。
    详细过程参考博客《http://blog.csdn.net/lastsweetop/article/details/9065667

03.复本的存放

NameNode节点选择一个datanode节点去存储block副本得过程就叫作副本存放,这个过程的策略其实就是在可靠性和读写带宽间得权衡。代理

《Hadoop权威指南》中的默认方式:

  1. 第一个复本会随机选择,可是不会选择存储过满的节点。
  2. 第二个复本放在和第一个复本不一样且随机选择的机架上。
  3. 第三个和第二个放在同一个机架上的不一样节点上。
  4. 剩余的副本就彻底随机节点了。

复本为3的系统管线:

能够看出这个方案比较合理:
1.可靠性:block存储在两个机架上
2.写带宽:写操做仅仅穿过一个网络交换机
3.读操做:选择其中得一个机架去读
4.block分布在整个集群上。

参考《Hadoop权威指南》和博客《http://blog.csdn.net/lastsweetop/article/details/9065667》 初接触,记下学习笔记,还有不少问题,望指导,谢谢。

相关文章
相关标签/搜索