在上一篇《大数据(2):Hadoop 启动进程》中详细分析了 Hadoop 进程的启动方法,这一篇将分析 Hadoop 中一个重要模块 HDFS。
一、什么是 HDFS
HDFS(Hadoop Distributed File System)是 Hadoop 项目的核心子项目,是分布式计算中数据存储管理的基础,是基于流数据模式访问和处理超大文件的需求而开发的,可以运行于商用服务器上。它所具有的高容错、高可靠性、高可扩展性、高获得性、高吞吐率等特征为海量数据提供了不怕故障的存储,为超大数据集(Large Data Set)的应用处理带来了很多便利。
二、HDFS 架构
整个 HDFS 集群由 NameNode 和 DataNode 构成主/从模式。一个 HDFS 集群在同一时间,只能有一个激活的 NameNode 名称节点,这是一个主服务器,它管理文件系统名称空间,并控制客户端对文件的访问,但从 Hadoop 3 开始,可以有多个待命态的 NameNode。
此外,还有多个 DataNodes 数据节点。这些 DataNodes 管理节点的存储。HDFS 公开一个文件系统名称空间,并允许用户数据存储在文件中。在内部,文件被分成一个或多个块,这些块存储在一组数据节点中。
hdfs architecture三、NameNode
NameNode 主要负责两件事情:维护文件系统目录和 DataNode 状态监控。
1. 维护文件系统目录
NameNode 负责整个分布式文件系统的元数据,包括文件目录树,文件到数据块 Block 的映射关系等。这些数据保存在内存里(这要求 NameNode 内存须足够大),同时这些数据还以两个文件形式永久保存在本地磁盘上:命名空间镜像文件 (fsimage) 和编辑日志文件 (edits)。
fsimage 文件存储的是文件系统元数据信息,如文件及目录结构,组成文件的块的信息,副本数量信息等;edits 文件则记录着用户对文件的各种操作记录,对 hdfs 中的文件进行新增或者修改操作,操作记录首先被记入 edits 文件中,当客户端操作成功后,相应的元数据会更新到内存 meta.data 中,防止发生意外导致丢失内存中的数据。fsimage 和 edits 两个文件结合可以构造出完整的内存数据。
注:在高可用模式下,edits 文件将不会存储在 NameNode 中,而是存储在 JournalNodes (JNs) 中。
当 Active NameNode 的名称空间修改时,会把修改内容记录到 JNs 中。Standby NameNode 能够从 JNs 读取修改内容,不断监听,并将这些修改,应用到自己的名称空间,以确保在发生故障之前完全同步名称空间状态。
2. 状态监控
NameNdoe 还负责对 DataNode 的状态监控。DataNode 通过心跳机制,定期向 NameNode 发送存储块的列表信息。NameNode 可以知道每个 DataNode 上保存着哪些数据(Block信息),DataNode 是否存活,并可以控制 DataNode 启动或停止。
若 NameNode 发现某个 DataNode 发生故障,会将其存储的数据在其他 DataNode 机器上增加相应的备份以维护数据副本(默认为3)保持不变。
如果把整个 HDFS 比作一本书,则 NameNode 相当于书的目录,记录着每一节的标题以及对应的页码;DataNode 相当于书的详细内容。由于书太厚,当想找书中的内容时,必须通过目录来查找。此外,若书的内容有修改,目录也需要做出调整,确保目录与内容一致。
如果 NaneNode 服务器失效,则整个集群将不可访问。因为我们无法知道哪些 DataNode 存储着哪些数据。但若部分 DataNode 节点失效,集群影响不大,任可正常对外提供服务。因此 NameNode 的高可用,容错机制很重要。
四、DataNode
DataNode 负责数据块的实际存储和读/写工作。
Hadoop 中,所有数据都被切分为一个或多个块 (block),每个块的默认大小为 128M。
当上传一个大文件时,HDFS 会将其切割成固定大小的 block,每个块以多份的形式存储在集群上,默认为 3 份。当需要查找这个文件时,并不是直接从 DataNode 读取这些 block 的信息,因为集群可能非常庞大,而这些 block 可能散落在不同的节点,因此需要先联系 NameNode,从 NameNode 中得知文件存储在哪些 DataNode 中,再从这些 DataNode 中读取数据。
例如,上传一个 300M 的文件时,HDFS 会将文件切割成 block0 + block1 + block2:128M + 128M + 44M,3 份 block 同时开始写入;当读取时,也将从 3 个 block 中同时读取,读取后再将 3 份 block 拼接成一个文件。
假设磁盘读取速度为 100M/s,则理论上,HDFS 读取 300M 文件需要 1.28s,而普通文件系统从头至尾读取,需要 3s。文件越大,HDFS 的优势越明显。
DataNode 进程死亡或者网络故障造成 DataNode 无法与 NameNode 通信,NameNode 不会立即把该节点判定为死亡,要经过一段时间,这段时间暂称作超时时长。
如果一台 DataNode 经过 10 分 30 秒(默认)后没有给 NameNode 发送心跳信息,而被 NameNode 判断为死亡,NameNode 会马上将其上的数据备份到集群中其他机器上。
当这个 DataNode 节点排除故障后,重新回到集群中,该节点上还保存着原来那批数据,而默认的配置情况下,DataNode 会每隔 60 分钟向 NameNode 发送一次 block 信息,在这段时间内,集群中会有某些数据块多出一个备份。在 NameNode 收到该节点的 block 信息后,它发现数据备份多了才会命令某些 DataNode 删除掉多余的备份数据。
五、上传文件到 HDFS
上传一个文件到 HDFS 集群分以下几步。
-
客户端创建文件;
-
向 namenode 请求上传文件,namenode 响应客户端是否可以上传文件,询问第一块 block 该上传到哪里,namenode 返回 3 个 datanode 地址给客户端;
-
客户端请求与最近的一个 datanode 节点 (假设为 datanode1) 建立传输通道 (data queue),并告知其还要传给 datanode2 和 datanode3。datanode1 会请求与 datanode2 建立连接 (pipeline),datanode2 请求与 datanode3 建立连接;
-
客户端收到通道建立成功的消息后,开始向 datanode1 发送 block1 的数据,以一个个 package (64k) 为单位通过通道向 datanode1 写数据,datanode1 收到数据会将其存在本地缓存中,一边向 datanode2 传数据,一边将缓存中的数据保存到磁盘上;
-
客户端在传送数据时会有一个 package 的应答队列,datanode1 每收到一个 package 后就向客户端发回消息 (ack),datanode1 不用等待 datandoe2 发回应答信息才给客户端发送信息,客户端只保证 datanode1 收到了数据就行,后面的事它交给了 datanode1,当一个 block 传输完成之后,客户端再次请求 namenode 上传第二个 block。
六、从 HDFS 下载文件
从 HDFS 集群中下载文件时,主要分以下几步。
-
跟 Namenode 通信,请求下载某个数据;
-
Namenode 查询元数据信息以及 block 位置信息,将数据所在的 Datanode 信息返回给客户端;
-
客户端根据数据所在的 Datanode,挑选一台距离自己最近的 Datanode,并向其发出下载文件的请求(若所需数据不在一台 Datanode 上保存,则分别向多台 Datanode 发出请求);
-
Datanode 响应客户端请求,将数据返回给客户端;
-
从多个 Datanode 获得的数据不断在客户端追加,形成完整的数据。
这一篇主要了解 HDFS 的两个关键节点:NameNode 和 DataNode,并分析了 HDFS 上传、下载文件的流程,解决了数据的分布式存储。下一篇《大数据(4):MapReduce》讲解 Hadoop 的并行计算框架。
网友评论