9.1 从HDFS读取数据的流程

9.1.1 剖析文件的读取

说明:

  • 客户端通过调用FileSystem对象的open()方法来打开希望读取的文件. 这个FileSystem对象是DistributedFileSystem的一个对象.

  • DistributedFileSystem通过RPC(远程过程调用)来调用namenode, 然后namenode就会返回这个文件的每一个快的位置信息(datanode的地址).

  • 返回的这些datanode会根据他们与客户端的距离进行排序.

  • open()方法返回的是一个FSDataInputStream对象. 通过这个对象就可以读取数据了. 这个对象管理着datanodedatanodeIO

  • 调用FSDataInputStream对象的read()方法, 则FSDataInputStream会从距离客户端最近的datanode读取第一个块的数据.

  • 随着反复的调用read(), 第一个块的数据被读完, 则关闭连接, 然后寻找下一个块的最佳datanode

  • 所有的这些操作都是透明的, 对客户端来说,仿佛他一直在读取一个连续的流一样.

  • 如果从datanode读取数据的时候遇到错误, 则会尝试从这个快的另一个最邻近的datanode读取数据.

  • 它也会记住那个故障datanode, 保证以后不会反复读取存储在该节点上的后续的块.

  • FSDataInputStream也会通过校验和确认从datanode发来的数据是否完整, 如果有损坏的块, 也会试图从其他datanode读取副本, 也会将损坏的块通知namenode


9.1.2 网络拓扑的概念

客户端读取数据的时候, 我们经常说从最近的datanode读取数据, 那么Hadoop是如何衡量客户端与datanode之间的远近的呢?

在海量数据处理中, 其主要限制因素是节点之间数据的传输速率(带宽的稀缺性). 所以, Hadoop将两个节点之间的带宽作为距离的衡量标准.

那么Hadoop又是如何衡量两个节点之间的带宽的呢? Hadoop采用了最简单的办法: 把网络看作一棵树, 则, 两个节点之间的距离是他们到共同的祖先(一般是网络交换机)的距离和.

节点表示法

假设有:

  • 数据中心:data1
  • 机架: rack1
  • 节点: node1

则节点node1可以表示为:data1/rack1/node1

四种距离分别为:

  • 同一节点上的进程间的距离: dis(data1/rack1/node1,data1/rack1/node1) = 0

  • 同一机架不同节点: dis(data1/rack1/node1,data1/rack1/node2) = 2

  • 同一数据中心, 不同机架: dis(data1/rack1/node1,data1/rack2/node1) = 4

  • 不同数据中心: dis(data1/rack1/node1,data2/rack1/node1) = 6

另外Hadoop并不能自动发现每个节点的网络拓扑结构, 我们需要进行相应的配置. 此处暂且不讲如何配置.


9.1.3 机架感知

如果Hadoop知道了网络拓扑结构, 那么, HDFS在存储数据的副本的时候, 是如何选择节点呢? 这就是所谓的机架感知(Rack Awareness).

Hadoop主要从数据可靠性和读写性能来选择副本的放置.

参考文章: http://hadoop.apache.org/docs/r2.7.2/hadoop-project-dist/hadoop-common/RackAwareness.html

http://hadoop.apache.org/docs/r2.7.2/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html#Data_Replication

现总结如下:

  1. 默认情况下, 每个数据块有三个副本.

  2. 第一个副本放在客户端(client)所在的datanode上. 如果client没有在datanode上, 则随机选一个datanode.

  3. 第二个副本放在与第一个副本同一个机架内的不同节点上.

  4. 第三个副本放在与第一第二副本不同的机架内的随机节点上.

Copyright © 尚硅谷大数据 2013-2019 all right reserved,powered by Gitbook
该文件最后修订时间: 2018-11-20 18:14:11

results matching ""

    No results matching ""