提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
Hadoop分布式系统
一、Hadoop系统架构
Hadoop的核心组件分为:
HDFS(分布式文件系统)、MapRuduce(分布式运算编程框架)、YARN(运算资源调度系统)
下图展示的是Hadoop的生态圈:
![在这里插入图片描述](https://img-blog.csdnimg.cn/275627e5396844f2b434c8fa0979f837.png#pic_center)
二、HDFS
HDFS是Hadoop分布式文件系统(Hadoop Distributed File System)的缩写,为分布式计算存储提供了底层支持。采用Java语言开发,可以部署在多种普通的廉价机器上,以集群处理数量积达到大型主机处理性能。
HDFS是Hadoop体系中数据存储管理的基础。它是一个高度容错的系统,能检测和应对硬件故障,用于在低成本的通用硬件上运行。HDFS简化了文件的一致性模型,通过流式数据访问,提供高吞吐量应用程序数据访问功能,适合带有大型数据集的应用程序。
1.设计理念
简单来讲,HDFS 的设计理念是,可以运行在普通机器上,以流式数据方式存储文件,一次写入、多次查询,具体有以下几点。
1) 可构建在廉价机器上
HDFS 的设计理念之一就是让它能运行在普通的硬件之上,即便硬件出现故障,也可以通过容错策略来保证数据的高可用性。
2)高容错性
由于 HDFS 需要建立在普通计算机上,所以结点故障是正常的事情。HDFS 将数据自动保存多个副本,副本丢失后,自动恢复,从而实现数据的高容错性。
3)适合批处理
HDFS 适合一次写入、多次查询(读取)的情况。在数据集生成后,需要长时间在此数据集上进行各种分析。每次分析都将涉及该数据集的大部分数据甚至全部数据,因此读取整个数据集的时间延迟比读取第一条记录的时间延迟更重要。
4) 适合存储大文件
这里说的大文件包含两种意思:一是值文件大小超过 100MB 及达到 GB 甚至 TB、PB 级的文件;二是百万规模以上的文件数量。
2.架构原理
HDFS采用master/slave架构。一个HDFS集群包含一个单独的NameNode和多个DataNode。
NameNode作为master服务,它负责管理文件系统的命名空间和客户端对文件的访问。NameNode会保存文件系统的具体信息,包括文件信息、文件被分割成具体block块的信息、以及每一个block块归属的DataNode的信息。对于整个集群来说,HDFS通过NameNode对用户提供了一个单一的命名空间。
DataNode作为slave服务,在集群中可以存在多个。通常每一个DataNode都对应于一个物理节点(当然也不排除每个物理节点可以有多个DataNode,不过生产环境里不建议这么做)。DataNode负责管理节点上它们拥有的存储,它将存储划分为多个block块,管理block块信息,同时周期性的将其所有的block块信息发送给NameNode。
Client 会分别访问 NameNode 和 DataNode 以获取文件的元信息及内容。HDFS 集群的 Client 将直接访问 NameNode 和 DataNode,相关数据会直接从 NameNode 或者 DataNode 传送到客户端。
在HDFS中,主要有三个角色,Client、NameNode、DataNode。
![在这里插入图片描述](https://img-blog.csdnimg.cn/6bfc36ea2f954b1c9f5e398f5fed21d9.png#pic_center)
2.文件写入与读取
文件写入
Client向NameNode发起文件写入的请求。NameNode根据文件大小和文件块配置情况,返回给Client它所管理部分DataNode的信息。Client将文件划分为多个block块,并根据DataNode的地址信息,按顺序写入到每一个DataNode块中。
具体步骤如下:
-
客户端调用 DistribuedFileSystem 的 Create() 方法来创建文件。
-
DistributedFileSystem 用 RPC 连接 NameNode,请求在文件系统的命名空间中创建一个新的文件;NameNode 首先确定文件原来不存在,并且客户端有创建文件的权限,然后创建新文件;DistributedFileSystem 返回 FSOutputStream 给客户端用于写数据。
-
客户端调用 FSOutputStream 的 Write() 函数,向对应的文件写入数据。
-
当客户端开始写入文件时,FSOutputStream 会将文件切分成多个分包(Packet),并写入其內部的数据队列。FSOutputStream 向 NameNode 申请用来保存文件和副本数据块的若干个 DataNode,这些 DataNode 形成一个数据流管道队列中的分包被打包成数据包,发往数据流管道中的第一个 DataNode。第一个 DataNode 将数据包发送给第二个 DataNode,第二个 DataNode 将数据包发送到第三个 DataNode。这样,数据包会流经管道上的各个 DataNode。
-
为了保证所有 DataNode 的数据都是准确的,接收到数据的 DataNode 要向发送者发送确认包(ACK Packet)。确认包沿着数据流管道反向而上,从数据流管道依次经过各个 DataNode,并最终发往客户端。当客户端收到应答时,它将对应的分包从内部队列中移除。
-
不断执行第 (3)~(5)步,直到数据全部写完。
-
调用 FSOutputStream 的 Close() 方法,将所有的数据块写入数据流管道中的数据结点,并等待确认返回成功。最后通过 NameNode 完成写入。
![在这里插入图片描述](https://img-blog.csdnimg.cn/d8a88ff3244643a2aa71dee485329e08.png#pic_center)
文件读取
Client向NameNode发起文件读取的请求。NameNode返回文件存储的block块信息、及其block块所在DataNode的信息。Client读取文件信息。
具体步骤如下:
-
客户端调用 DistributedFileSystem 的 Open() 方法打开文件。
-
DistributedFileSystem 用 RPC 连接到 NameNode,请求获取文件的数据块的信息;NameNode 返回文件的部分或者全部数据块列表;对于每个数据块,NameNode 都会返回该数据块副本的 DataNode 地址;DistributedFileSystem 返回 FSDataInputStream 给客户端,用来读取数据。
-
客户端调用 FSDataInputStream 的 Read() 方法开始读取数据。
-
FSInputStream 连接保存此文件第一个数据块的最近的 DataNode,并以数据流的形式读取数据;客户端多次调用 Read(),直到到达数据块结束位置。
-
FSInputStream连接保存此文件下一个数据块的最近的 DataNode,并读取数据。
-
当客户端读取完所有数据块的数据后,调用 FSDataInputStream 的 Close() 方法。
![在这里插入图片描述](https://img-blog.csdnimg.cn/6210815149c94d618286531e9e140e4e.png#pic_center)
4.数据备份
HDFS被设计成一个可以在大集群中、跨机器、可靠的存储海量数据的框架。它将所有文件存储成block块组成的序列,除了最后一个block块,所有的block块大小都是一样的。文件的所有block块都会因为容错而被复制。每个文件的block块大小和容错复制份数都是可配置的。容错复制份数可以在文件创建时配置,后期也可以修改。HDFS中的文件默认规则是write one(一次写、多次读)的,并且严格要求在任何时候只有一个writer。NameNode负责管理block块的复制,它周期性地接收集群中所有DataNode的心跳数据包和Blockreport。心跳包表示DataNode正常工作,Blockreport描述了该DataNode上所有的block组成的列表。
备份数据的存放
备份数据的存放是HDFS可靠性和性能的关键。HDFS采用一种称为rack-aware的策略来决定备份数据的存放。通过一个称为Rack Awareness的过程,NameNode决定每个DataNode所属rack id。缺省情况下,一个block块会有三个备份,一个在NameNode指定的DataNode上,一个在指定DataNode非同一rack的DataNode上,一个在指定DataNode同一rack的DataNode上。这种策略综合考虑了同一rack失效、以及不同rack之间数据复制性能问题。
副本的选择
为了降低整体的带宽消耗和读取延时,HDFS会尽量读取最近的副本。如果在同一个rack上有一个副本,那么就读该副本。如果一个HDFS集群跨越多个数据中心,那么将首先尝试读本地数据中心的副本。
三、MapReduce
1.设计思想
MapReduce是分布式运行的,由两个阶段组成:Map和Reduce, Map阶段是一个独立的程序,在很多个节点同时运行,每个节点处理一部分数据。 Reduce阶段也是一个独立的程序,可以在一个或者多个节点同时运行,每个节点处理一部分数据。map就是对数据进行局部汇总,reduce就是对局部数据进行最终汇总。
2.架构原理
一个完整的MapReduce程序在分布式运行时有三类实例进程:
- MRAppMaster:负责整个程序过程调度及状态协调
- MapTask:负责map阶段整个数据处理流程
- ReduceTask:负责reduce阶段整个数据处理流程
注意:MapTask和RedueceTask都是进程级别。
各实例作用:
![在这里插入图片描述](https://img-blog.csdnimg.cn/a02748ee8b094aa88f5d21710f5c4379.png#pic_center)
3.计算流程
参考博客
1.读取输入文件(HDFS)内容,解析成key1、value1
2.【Map阶段】MapTask负责拆分,对输入的key1、value1调用map函数处理转换成新的key2、value2输出
3.【分区】对输出的key2、value2进行分区(默认只有一个分区)。一个分区对应一个Reduce
4.【排序】对不同分区的数据,按照key进行排序
5.【规约】进行规约(优化MR程序,提高效率)。一般都是使用默认的
6.【分组】将相同key值数据合并成一个集合,获得新的key2、value2集合
7.【Reduce阶段】ReduceTask负责合并,将key2、value2合并数据获得新的key3、value3
8.把reduce的输出保存到文件(HDFS)中
四、YARN
总结
参考文章1