阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Hadoop中HDFS读取和写入的工作原理

173次阅读
没有评论

共计 4145 个字符,预计需要花费 11 分钟才能阅读完成。

介绍

HDFS 和 HBase 是 Hadoop 中两种主要的存储文件系统,两者适用的场景不同,HDFS 适用于大文件存储,HBASE 适用于大量小文件存储。本文主要讲解 HDFS 文件系统中客户端是如何从 Hadoop 集群中读取和写入数据的,也可以说是 block 策略。

正文

一 写入数据

当没有配置机架信息时,所有的机器 hadoop 都默认在同一个默认的机架下,名为“/default-rack”,这种情况下,任何一台 datanode 机器,不管物理上是否属于同一个机架,都会被认为是在同一个机架下,此时,就很容易出现之前提到的增添机架间网络负载的情况。在没有机架信息的情况下,namenode 默认将所有的 slaves 机器全部默认为在 /default-rack 下

而当 Hadoop 集群中配置了机架感知信息以后,hadoop 在选择三个 datanode 时,就会进行相应的判断:

1. 如果上传本机不是一个 datanode,而是一个客户端,那么就从所有 slave 机器中随机选择一台 datanode 作为第一个块的写入机器 (datanode1)。

注意:而此时如果上传机器本身就是一个 datanode(例如 mapreduce 作业中 task 通过 DFSClient 向 hdfs 写入数据的时候),那么就将该 datanode 本身作为第一个块写入机器 (datanode1)。

2. 随后在 datanode1 所属的机架以外的另外的机架上,随机的选择一台,作为第二个 block 的写入 datanode 机器 (datanode2)。

3. 在写第三个 block 前,先判断是否前两个 datanode 是否是在同一个机架上,如果是在同一个机架,那么就尝试在另外一个机架上选择第三个 datanode 作为写入机器 (datanode3)。而如果 datanode1 和 datanode2 没有在同一个机架上,则在 datanode2 所在的机架上选择一台 datanode 作为 datanode3。

4. 得到 3 个 datanode 的列表以后,从 namenode 返回该列表到 DFSClient 之前,会在 namenode 端首先根据该写入客户端跟 datanode 列表中每个 datanode 之间的“距离”由近到远进行一个排序。如果此时 DFS 写入端不是 datanode,则选择 datanode 列表中的第一个排在第一位。客户端根据这个顺序有近到远的进行数据块的写入。在此,判断两个 datanode 之间“距离”的算法就比较关键,hadoop 目前实现如下,以两个表示 datanode 的对象 DatanodeInfo(node1,node2) 为例:

a) 首先根据 node1 和 node2 对象分别得出两个 datanode 在整个 hdfs 集群中所处的层次。这里的层次概念需要解释一下:每个 datanode 在 hdfs 集群中所处的层次结构字符串是这样描述的,假设 hdfs 的拓扑结构如下:

每个 datanode 都会对应自己在集群中的位置和层次,如 node1 的位置信息为“/rack1/datanode1”, 那么它所处的层次就为 2,其余类推。得到两个 node 的层次后,会沿着每个 node 所处的拓朴树中的位置向上查找,如“/rack1/datanode1”的上一级就是“/rack1”,此时两个节点之间的距离加 1,两个 node 分别同上向上查找,直到找到共同的祖先节点位置,此时所得的距离数就用来代表两个节点之间的距离。所以,如上图所示,node1 和 node2 之间的距离就为 4.

5. 当根据“距离”排好序的 datanode 节点列表返回给 DFSClient 以后,DFSClient 便会创建 BlockOutputStream,并将这次 block 写入 pipeline 中的第一个节点(最近的节点)。

6. 写完第一个 block 以后,依次按照 datanode 列表中的次远的 node 进行写入,直到最后一个 block 写入成功,DFSClient 返回成功,该 block 写入操作结束。

通过以上策略,namenode 在选择数据块的写入 datanode 列表时,就充分考虑到了将 block 副本分散在不同机架下,并同时尽量的避免了之前描述的过多的网络开销。

补充:Hadoop 机架的感知策略

默认情况下,hadoop 的机架感知是没有被启用的。所以,在通常情况下,hadoop 集群的 HDFS 在选机器的时候,是随机选择的,也就是说,很有可能在写数据时,hadoop 将第一块数据 block1 写到了 rack1 上,然后随机的选择下将 block2 写入到了 rack2 下,此时两个 rack 之间产生了数据传输的流量,再接下来,在随机的情况下,又将 block3 重新又写回了 rack1,此时,两个 rack 之间又产生了一次数据流量。在 job 处理的数据量非常的大,或者往 hadoop 推送的数据量非常大的时候,这种情况会造成 rack 之间的网络流量成倍的上升,成为性能的瓶颈,进而影响作业的性能以至于整个集群的服务。

要将 hadoop 机架感知的功能启用,配置非常简单,在 namenode 所在机器的 hadoop-site.xml 配置文件中配置一个选项:

<property>

<name>topology.script.file.name</name>

<value>/path/to/RackAware.py</value>

</property>

这个配置选项的 value 指定为一个可执行程序,通常为一个脚本,该脚本接受一个参数,输出一个值。接受的参数通常为某台 datanode 机器的 ip 地址,而输出的值通常为该 ip 地址对应的 datanode 所在的 rack,例如”/rack1”。Namenode 启动时,会判断该配置选项是否为空,如果非空,则表示已经用机架感知的配置,此时 namenode 会根据配置寻找该脚本,并在接收到每一个 datanode 的 heartbeat 时,将该 datanode 的 ip 地址作为参数传给该脚本运行,并将得到的输出作为该 datanode 所属的机架,保存到内存的一个 map 中。

至于脚本的编写,就需要将真实的网络拓朴和机架信息了解清楚后,通过该脚本能够将机器的 ip 地址正确的映射到相应的机架上去。一个简单的实现如下:

#!/usr/bin/Python
#-*-coding:UTF-8 -*-
import sys

rack = {“hadoopnode-176.tj”:”rack1″,
“hadoopnode-178.tj”:”rack1″,
“hadoopnode-179.tj”:”rack1″,
“hadoopnode-180.tj”:”rack1″,
“hadoopnode-186.tj”:”rack2″,
“hadoopnode-187.tj”:”rack2″,
“hadoopnode-188.tj”:”rack2″,
“hadoopnode-190.tj”:”rack2″,
“192.168.1.15”:”rack1″,
“192.168.1.17”:”rack1″,
“192.168.1.18”:”rack1″,
“192.168.1.19”:”rack1″,
“192.168.1.25”:”rack2″,
“192.168.1.26”:”rack2″,
“192.168.1.27”:”rack2″,
“192.168.1.29”:”rack2″,
}

if __name__==”__main__”:
print “/” + rack.get(sys.argv[1],”rack0″)

由于没有找到确切的文档说明 到底是主机名还是 ip 地址会被传入到脚本,所以在脚本中最好兼容主机名和 ip 地址,如果机房架构比较复杂的话,脚本可以返回如:/dc1/rack1 类似的字符串。

二 读取数据

我们看一下 Hadoop 集群配置中如何读取数据。当对某个文件的某个 block 进行读取的时候,hadoop 采取的策略也是一样:

1. 首先得到这个 block 所在的 datanode 的列表,有几个副本数该列表就有几个 datanode。

2. 根据列表中 datanode 距离读取端的距离进行从小到大的排序:

a) 首先查找本地是否存在该 block 的副本,如果存在,则将本地 datanode 作为第一个读取该 block 的 datanode

b) 然后查找本地的同一个 rack 下是否有保存了该 block 副本的 datanode

c) 最后如果都没有找到,或者读取数据的 node 本身不是 datanode 节点,则返回 datanode 列表的一个随机顺序。

————————————– 分割线 ————————————–

将本地文件拷到 HDFS 中 http://www.linuxidc.com/Linux/2013-05/83866.htm

从 HDFS 下载文件到本地 http://www.linuxidc.com/Linux/2012-11/74214.htm

将本地文件上传至 HDFS http://www.linuxidc.com/Linux/2012-11/74213.htm

HDFS 基本文件常用命令 http://www.linuxidc.com/Linux/2013-09/89658.htm

Hadoop 中 HDFS 和 MapReduce 节点基本简介 http://www.linuxidc.com/Linux/2013-09/89653.htm

《Hadoop 实战》中文版 + 英文文字版 + 源码【PDF】http://www.linuxidc.com/Linux/2012-10/71901.htm

Hadoop: The Definitive Guide【PDF 版】http://www.linuxidc.com/Linux/2012-01/51182.htm

————————————– 分割线 ————————————–

更多 Hadoop 相关信息见 Hadoop 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=13

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-20发表,共计4145字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中