我们继续在 FileSystem 类分析,读数据使用的是 open(…)方法,我们可以看到源码

FSDataInputStream in = fileSystem.open(new Path("/d100/f1"));

点击open

  /**
   * Opens an FSDataInputStream at the indicated Path.
   * @param f the file to open
   */
  public FSDataInputStream open(Path f) throws IOException {
    return open(f, getConf().getInt("io.file.buffer.size", 4096));
  }

在return open 的open按ctrl+t 选择第一个DistributedFileSystem

  public FSDataInputStream open(Path f, int bufferSize) throws IOException {
    statistics.incrementReadOps(1);
    return new DFSClient.DFSDataInputStream(
          dfs.open(getPathName(f), bufferSize, verifyChecksum, statistics));
  }

返回的是 DFSClient 类中 DFSDataInputStream 类,显而易见,这是一个内部类。这个内部类的构造函数,有两个形参,第一个参数是 dfs.open(…)创建的对象。我们

看一下方法的源码,

  /**
   * Create an input stream that obtains a nodelist from the
   * namenode, and then reads from all the right places.  Creates
   * inner subclass of InputStream that does the right out-of-band
   * work.
   */
  public DFSInputStream open(String src, int buffersize, boolean verifyChecksum,
                      FileSystem.Statistics stats
      ) throws IOException {
    checkOpen();
    //    Get block info from namenode
    return new DFSInputStream(src, buffersize, verifyChecksum);
  }

返回的是一个 DFSInputStream 对象。该对象中含有 NameNode 中的数据块信息。我们看一下这个类的构造方法源码

    DFSInputStream(String src, int buffersize, boolean verifyChecksum
                   ) throws IOException {
      this.verifyChecksum = verifyChecksum;
      this.buffersize = buffersize;
      this.src = src;
      prefetchSize = conf.getLong("dfs.read.prefetch.size", prefetchSize);
      openInfo();
    }

openInfo()打开信息,openInfo()的源代码是获取数据块的信息的。我们查看这一行的源代码

    /**
     * Grab the open-file info from namenode
     */
    synchronized void openInfo() throws IOException {
      for (int retries = 3; retries > 0; retries--) {
        if (fetchLocatedBlocks()) {
          // fetch block success
          return;
        } else {
          // Last block location unavailable. When a cluster restarts,
          // DNs may not report immediately. At this time partial block
          // locations will not be available with NN for getting the length.
          // Lets retry a few times to get the length.
          DFSClient.LOG.warn("Last block locations unavailable. "
              + "Datanodes might not have reported blocks completely."
              + " Will retry for " + retries + " times");
          waitFor(4000);
        }
      }
      throw new IOException("Could not obtain the last block locations.");
    }

进去fetchLocatedBlocks()

    private boolean fetchLocatedBlocks() throws IOException,
        FileNotFoundException {
      LocatedBlocks newInfo = callGetBlockLocations(namenode, src, 0,
          prefetchSize);
      if (newInfo == null) {
        throw new FileNotFoundException("File does not exist: " + src);
      }

      if (locatedBlocks != null && !locatedBlocks.isUnderConstruction()
          && !newInfo.isUnderConstruction()) {
        Iterator<LocatedBlock> oldIter = locatedBlocks.getLocatedBlocks()
            .iterator();
        Iterator<LocatedBlock> newIter = newInfo.getLocatedBlocks().iterator();
        while (oldIter.hasNext() && newIter.hasNext()) {
          if (!oldIter.next().getBlock().equals(newIter.next().getBlock())) {
            throw new IOException("Blocklist for " + src + " has changed!");
          }
        }
      }
      boolean isBlkInfoUpdated = updateBlockInfo(newInfo);
      this.locatedBlocks = newInfo;
      this.currentNode = null;
      return isBlkInfoUpdated;
    }

进入:callGetBlockLocations(namenode, src, 0, prefetchSize);

  static LocatedBlocks callGetBlockLocations(ClientProtocol namenode,
      String src, long start, long length) throws IOException {
    try {
      return namenode.getBlockLocations(src, start, length);
    } catch(RemoteException re) {
      throw re.unwrapRemoteException(AccessControlException.class,
                                    FileNotFoundException.class);
    }
  }

可以看到,获取数据块信息的方法也是通过调用 namenode 取得的。这里的 namenode 属性还是位于 DFSClient 中的。通过前面的分析,我们已经知道,在 DFSClient类中的 namenode 属性是 ClientProtocal。

可以参考上一篇文章 写数据的分析

HDFS的读数据过程分析的更多相关文章

  1. HDFS的写数据过程分析

    HDFS的写数据过程分析 我们通过FileSystem类可以操控HDFS, 那我们就从这里开始分析写数据到HDFS的过程. 在我们向 HDFS 写文件的时候,调用的是 FileSystem.creat ...

  2. HDFS数据流——读数据流程

    HDFS读数据流程 假设客户端请求下载文件/user/atguigu/ss.avi,HDFS读数据流程如下: 1)客户端向namenode请求下载文件,namenode通过查询元数据,找到文件所有文件 ...

  3. Hadoop日记Day11---主从节点接口分析

    一.NameNode 的接口分析 1. NameNode本质 经过前面的学习,可以知道NameNode 本身就是一个java 进程.观察RPC.getServer()方法的第一个参数,发现是this, ...

  4. hadoop入门级总结一:HDFS

    虽然hadoop经历了多年的发展,作为技术人员都或多或少的使用过或者了解过.这里还是做一个简单的总结,主要原因是之前主要是做hadoop的开发,对hadoop的运维知之甚少,但真正的接触到hadoop ...

  5. hadoop之HDFS学习笔记(一)

    主要内容:hdfs的整体运行机制,DATANODE存储文件块的观察,hdfs集群的搭建与配置,hdfs命令行客户端常见命令:业务系统中日志生成机制,HDFS的java客户端api基本使用. 1.什么是 ...

  6. Hadoop(8)-HDFS的读写数据流程以及机架感知

    1. HDFS的写数据流程 1.客户端通过fs模块向NameNode申请文件上传,NameNode检查请求是否合法,如用户权限,目标文件是否已存在,父目录是否存在等等 2.NameNode返回是否可以 ...

  7. HDFS HA架构以及源代码引导

    HA体系架构 相关知识介绍 HDFS master/slave架构,HDFS节点分为NameNode节点和DataNode节点. NameNode存有HDFS的元数据:主要由FSImage和EditL ...

  8. Hadoop_08_客户端向HDFS读写(上传)数据流程

    1.HDFS的工作机制: HDFS集群分为两大角色:NameNode.DataNode (Secondary Namenode) NameNode负责管理整个文件系统的元数据 DataNode 负责管 ...

  9. 大数据技术之Hadoop(HDFS)

    第1章 HDFS概述 1.1 HDFS产出背景及定义 1.2 HDFS优缺点 1.3 HDFS组成架构 1.4 HDFS文件块大小(面试重点) 第2章 HDFS的Shell操作(开发重点) 1.基本语 ...

随机推荐

  1. python 云打码 hhtp接口

    import http.client, mimetypes, urllib, json, time, requests ######################################## ...

  2. [HNOI 2015]开店

    Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...

  3. [HNOI 2013]比赛

    Description 沫沫非常喜欢看足球赛,但因为沉迷于射箭游戏,错过了最近的一次足球联赛.此次联 赛共N支球队参加,比赛规则如下: (1) 每两支球队之间踢一场比赛. (2) 若平局,两支球队各得 ...

  4. UVA - 11732:"strcmp()" Anyone?

    字典树问题 对于普通的字典树,可以加一个vector数组记录非空的孩子,加快速度 还可以用左孩子右兄弟来节省空间,因为普通的trie的话是 int next[MAXN][26] 而左孩子右兄弟可以把[ ...

  5. hdu 3308 最长连续上升区间

    LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  6. [4.14校内训练赛by hzwer]

    来自FallDream的博客,未经允许,请勿转载,谢谢. hzwer又出丧题虐人 4道noi....        很奇怪 每次黄学长出题总有一题我做过了. 嗯题目你们自己看看呗 好难解释 ----- ...

  7. EF 6.x、EF Core实现dynamic动态查询和EF Core实现多个上下文实例池你了解多少?

    前言 很长一段时间没有写博客了,今天补上一篇吧,偶尔发现不太愿意写博客了,太耗费时间,不过还是在坚持当中,毕竟或许写出来的东西能帮到一些童鞋吧,接下来我们直奔主题.无论是在在EF 6.x还是EF Co ...

  8. python中decode

    这 是因为遇到了非法字符--尤其是在某些用C/C++编写的程序中,全角空格往往有多种不同的实现方式,比如\xa3\xa0,或者\xa4\x57,这些 字符,看起来都是全角空格,但它们并不是" ...

  9. IntelliJ IDEA设置统一编码utf-8

    File菜单->Other Settings->Default Settings->File Encodings 全改成utf-8!

  10. 在vue中操作DOM--this.$nextTick()

    虽然 Vue.js 通常鼓励开发人员沿着"数据驱动"的方式思考,避免直接接触 DOM,但是有时我们确实要这么做.比如一个新闻滚动的列表项.如果在这里需要操作dom, 应该是等待 V ...