7.1 Hadoop的优化与发展
7.1.1 Hadoop的局限和不足
Hadoop在刚刚推出时,存在很多不足。存在的不足如下:
- 抽象层次低,需人工编码。
很多工作没有办法从高层撰写逻辑代码,必须从最底层进行逻辑编码。即使是很简单的任务都要编写完整的MapReduce代码,然后进行编译、打包、运行。 - 表达能力有限
在Hadoop核心组件中,MapReduce负责计算,虽然它将复杂的分布式计算全部抽象为Map和Reduce函数,简化了编程工作。但同时这种方法也限制了表达能力,现实中的很多问题没有办法使用Map和Reduce函数完成。 - 开发者自己管理作业(Job)之间的依赖关系
在企业中,许多大问题的解决需要借助多个MapReduce作业才能完成,这些MapReduce作业之间实际上是相互依赖的关系,需要完成某个MapReduce作业后,将结果提交到另外一个MapReduce作业进行处理,即多个MapReduce作业之间构成了工作流,有先后关系。但是这种先后关系在Hadoop1.0中无法通过产品本身的功能实现,所以开发人员不得不通过编码的方式,将这种依赖关系写入代码,从而实现不同作业之间的相互依赖。 - 难以看到程序的整体逻辑
在Hadoop1.0中,没有为用户提供高层逻辑表现方式。用户想了解程序是按照什么顺序执行的,只能去看源代码,一行行的分析处理逻辑,这对用户是困难的工作,对代码维护不利。 - 执行迭代操作效率低
MapReduce是将作业分阶段进行的,每次MapReduce任务完成之后,都要写入到分布式文件系统HDFS中,供下一个MapReduce使用。不同阶段之间需要迭代,这种迭代与数据传递,都要先把数据写入HDFS再给下一个MapReduce用。在数据挖掘和机器学习中,有非常多的迭代过程,如果采用MapReduce进行这种迭代,效率非常低。 - 资源浪费
整个任务执行时,严格划分阶段(Map和Reduce)。要求所有Map任务处理结束之后,才能进入Reduce。在等待Map任务的过程中,Reduce一直是空闲的,造成了资源浪费。 - 实时性差
MapReduce框架很难实现实时交互查询。
7.1.2 Hadoop的改进和提升
Hadoop的优化与发展主要体现在两个方面:
- Hadoop自身两大核心组件,MapReduce和HDFS架构设计改进。
Hadoop模块的自身改进:从1.0到2.0。
- Hadoop生态系统其他组件的不断丰富,包括Pig,Tez,Spark和Kafka等。
pig:提供类似SQL语法的语句,提高编程效率。用户执行分析任务时,只需要编写几行简单的代码即可完成任务。
spark:MapReduce是基于磁盘的,不同阶段之前通过磁盘进行数据交换。而spark的数据处理、传输过程全部通过内存进行交换,迭代效率非常高。
Oozie:帮助用户有效管理多个MapReduce任务之间的相互依赖关系。
Tez:是支持有向无环图作业的计算框架,对整个MapReduce作业分解成更多的子操作,减少了不同MapReduce之间的重复操作。
Kafka:Hadoop生态系统中的多个组件之间需要进行数据交互,可以通过Kafka,将其他类型的分布式系统接入(比如NoSQL、日志系统),实现与Hadoop各个组件之间的数据交换。
7.2 HDFS2.0的新特性
7.2.1 HDFS HA
回顾在HDFS1.0中介绍的核心组件,如下图所示。
在1.0中,HDFS集群就是由一个名称节点和若干个数据节点构成的,名称节点提供元数据服务,数据节点负责数据存储。名称节点保存的元数据包括整个文件系统树的镜像文件(FsImage)以及日志文件(EditLog),这两个文件保存在磁盘上。同时,名称节点也保存着映射信息,即一个文件包含哪些块、每个块保存在哪个数据节点上,这些映射信息保存在内存中。
由于在HDFS1.0中只有一个名称节点,所以一旦名称节点产生问题,就会发生单点故障,整个系统就会宕机。在1.0中即使存在第二名称节点(Secondary NameNode),也不能解决单点故障问题。
在HDFS2.0中,引入的HDFS HA(High Availability)就是为了解决单点故障问题,其架构如下图所示。
HA集群设置了两个名称节点,一个被设置为活跃状态(Active),一个被设置为待命状态(Standby)。一旦活跃名称节点出现了故障,就可以马上切换到代码名称节点,这种方式称为热备份。
由于同一时间只能有一个NameNode作为管家工作,所以需要Zookeeper确保某个时刻只有一个名称节点在对外服务。
状态信息的同步:对于映射表的维护,所有数据节点需要向两个名称节点汇报信息,以便名称节点更新自己内存中的映射表,保证两个名称节点保存的元数据是实时一致的。对于EditLog的维护,两种名称节点状态同步借助于一个共享存储系统实现,活跃节点通过共享存储系统,将新的信息传递给待命节点。
7.2.2 HDFS Federation
HDFS1.0中存在的问题
- 单点故障问题
这个问题可以使用HDFS HA中的热备份解决,但是下面几个问题是无法通过HA解决的。 - 不可以水平扩展
不能添加名称节点。虽然HA提供了备份,但备份的名称节点只会在出现故障的时候才进行顶替。在某一时刻实际发挥作用的仍然只有一个名称节点。
是否能通过纵向扩展(让名称节点保持更多元数据信息、支持更大规模文件存储。需要加内存和CPU)实现呢?不能。HDFS中名称节点中很多元数据信息都保存在内存中。内存过大会导致启动速度过慢。并且,内存过大会导致一旦垃圾清理过程发生问题,整个系统宕机。 - 系统整体性能受限于单个名称节点的吞吐量
真正提供服务的只有一个处于活跃状态的名称节点,吞吐量是由单个节点决定的。 - 单个名称节点难以提供不同程序之间的隔离性
一个应用程序消耗的CPU和内存资源可能非常大,一旦将多个程序放到一起运行,可能一个应用程序就将资源消耗完了,其他程序无法运行。 - HDFS HA是热备份,提供高可用性,但是无法解决可扩展性、系统性能和隔离性
HDFS Federation 架构示意图:
在2.0中,由图可见已经包含多个相互独立的名称节点,使得HDFS的命名服务能够水平扩展,并且这些名称节点之间彼此工作相互独立、分别进行各自命名空间和块的管理,构成联盟关系,无需进行协调。并且这种机制是向后兼容的,之前基于单名称节点开发的程序可以无缝迁移到已经采用多名称节点的框架中。
每一个名称节点都管理着自己的命名空间,所有名称节点都共享底层公共的数据节点存储资源,数据节点向所有名称节点汇报。属于同一个命名空间的块构成一个"块池"(是逻辑上的概念,不是物理概念,还是要依靠底层的数据节点存储物理数据)。
数据访问方式
对于Federation中的多个命名空间,可以采用客户端挂载表(Client Side Mount Table)的方式进行数据共享和访问。客户可以通过访问不同的挂载点来访问不同的子命名空间。
客户挂载表方式访问多个命名空间示意图
在下图中,上面的三角形区域是从用户角度看到的全局命名空间,包括data、project、home、tmp四个子命名空间。下面的阴影区域是每一个名称节点维持的子命名空间,可以把各个命名空间挂载到全局"挂载表"(mount-table)中,实现全局数据共享。
若将各个命名空间挂载到全局挂载表,就可以从全局看到各个子命名空间,可以选择指定命名空间访问数据。若将相同的命名空间挂载到个人的挂载表中,就成为了应用程序可见的命名空间,应用程序可以直接访问子命名空间。
HDFS Federation相对于HDFS1.0的优势
HDFS Federation设计可以解决单名称节点存在的以下问题:
- HDFS 集群扩展性。Federation中有多个名称节点,每个名称节点可以各自管理一部分目录,可以让一个集群扩展到更多节点。不再像HDFS1.0中那样由于内存的限制制约文件存储数目(一个名称节点能存储的文件数目是有限的)。
- 性能更高效。多个名称节点各自管理不同的数据,并且可以同时对外提供服务,因此可以提供更高的数据吞吐率。
- 良好的隔离性。可以根据不同业务进行子空间的划分,某种数据可以归属于一个名称节点管理,另外的数据可能归属于另一个名称节点管理。不同数据分给不同名称节点管理,可以有效的对不同业务之间进行隔离,不会因为一个应用程序消耗过多资源而影响另一个应用程序运行。
注意:虽然HDFS Federation相当于1.0版本具备很多优势,但是它不能解决单点故障问题。虽然它存在多个名称节点,但是对每个名称节点来说都存在单点故障问题(名称节点之间是联盟关系而不是备份关系),需要为每个名称节点部署一个后备名称节点、启用HA高可用性机制,以应对名称节点宕机对业务产生的影响。
7.3 新一代资源管理调度框架YARN
7.3.1 MapReduce1.0的缺陷
正是因为MapReduce1.0中存在的缺陷,才会有YARN的诞生。
MapReduce1.0体系结构如下:
MapReduce1.0的缺陷如下:
- 存在单点故障。
在1.0体系架构中只有JobTracker作为总管家,负责整个作业的调度、管理、监控、资源调度。JobTracker收到任务后,将之分解为多个作业,分配到TaskTracker。因此,JobTracker如果宕机,MapReduce就没有办法使用了。 - JobTracker"大包大揽"导致任务过重
JobTracker作为总管家,既要负责资源管理调度分配,也要负责任务的调度、监控,以及失败的恢复。一旦对内存消耗大的多个任务同时运行,内存开销非常大,非常容易导致出现故障。因此,业界发现对MapReduce作集群的时候,上限就是4000个节点。 - 容易出现内存溢出
分配资源时,仅仅考虑MapReduce任务数,而不考虑每个MapReduce任务到底消耗多少CPU、消耗多少内存。一旦多个内存消耗大的任务一起执行时,内存就会溢出。 - 资源划分不合理
把CPU、内存等资源打包后,强行等分成多个slot,并分为Map slot(只能给Map任务用)和Reduce slot(只能给Reduce任务用)。即使Reduce任务是空闲的,而Map任务安排的非常繁忙,也不能将Reduce的资源分配给Map用,因为他们不能互相使用。
7.3.2 YARN设计思路
YARN架构思路如下:
正是因为MapReduce存在上述问题,所以YARN进行了有针对性的改进。基本思想是将原JobTracker功能进行拆分,把资源管理功能分配给新的组件ResourceManager,任务调度和任务监控交给组件ApplicationMaster。原来TaskTracker的任务交给NodeManager管理。
MapReduce1.0既是一个计算框架,也是一个资源管理调度框架。
而到了Hadoop2.0之后,MapReduce1.0中的资源管理调度功能,被单独分离出来形成了YARN,YARN是纯粹的资源管理调度框架,不再是一个计算框架。
被剥离了资源管理调度功能的MapReduce框架就变成了MapReduce2.0,它是运行在YARN上的一个纯粹的计算框架,不再自己负责资源调度管理服务,而是由YARN为其提供资源管理调度服务。
7.3.3 YARN体系结构
YARN体系结构如下图所示,包含三大核心组件:
1.ResourceManager:处理客户端请求、启动/监控ApplicationMaster、监控NodeManager、资源分配与调度。
2.ApplicationMaster:为应用程序申请资源并分配给内部任务、任务调度/监控/容错。
3.NodeManager:单个节点上的资源管理、处理来自ResourceManager的命令、处理来自ApplicationMaster的命令。
ResourceManager
简称RM,是一个全局的资源管理器,负责整个系统的资源管理和分配,主要包括两个组件,即调度器(Scheduler)和应用程序管理器(Applications Manager)。
调度器接受来自ApplicationMaster的应用程序资源请求,把集群中的资源以"容器"的形式分配给提出申请的应用程序。容器的选择通常会考虑应用程序要处理的数据的位置,进行就近选择,从而实现"计算向数据靠拢"。
容器(Container)作为动态资源分配单位,每个容器中都封装了一定数量的CPU、内存、磁盘等资源,从而限定每个应用程序可以使用的资源量。
调度器被设计成是一个可插拔的组件,YARN不仅自身提供了许多种直接可用的调度器,也允许用户根据自己的需求重新设计调度器。
应用程序管理器负责所有应用程序的管理工作,主要包括应用程序提交、与调度器协商资源以启动ApplicationMaster、监控ApplicationMaster运行状态并在失败时重新启动等。注意,应用程序管理器不会涉及到具体任务的管理执行,只会监控ApplicationMaster。
ApplicationMaster
ResourceManager接受用户提交的作业,按照作业的上下文信息以及从NodeManager收集来的容器信息,启动调度过程,为用户作业启动一个ApplicationMaster(ApplicationMaster也是在容器上运行的,因此ResourceManager需要先给它申请一个容器)。
ApplicationMaster的主要功能:
- 当用户作业(应用程序以作业的形式提交给Hadoop系统,Hadoop再将它分解成多个Map任务和Reduce任务执行)提交时,ApplicationMaster与ResourceManager协商获取资源,ResourceManager会以容器的形式为ApplicationMaster分配资源。
- 把获得的资源进一步分配给内部的各个任务(Map任务或Reduce任务),实现资源的"二次分配"。
- 与NodeManager保持交互通信,进行应用程序的启动、运行、监控和停止,监控申请到的资源的使用情况,对所有任务的执行进度和状态进行监控,并在任务发生失败时执行失败恢复(即重新申请资源重启任务)。
- 定时向ResourceManager发送"心跳"信息(以便用户通过ResourceManager查询整个作业当前运行状态),报告资源的使用情况和应用的进度信息。
- 当作业完成时,ApplicationMaster向ResourceManager注销容器,执行周期完成。
NodeManager
NodeManager是驻留在一个YARN集群中的每个节点上的代理,主要负责如下:
- 容器生命周期管理:集群中的各种资源都是以容器的形式存在的,容器就是由NodeManager管理的。容器中运行ApplicationMaster,可以支持任务的运行
- 监控每个容器的资源(CPU、内存等)使用情况
- 跟踪节点监控状况
- 以"心跳"的方式与ResourceManager保持通信
- 向ResourceManager汇报作业的资源使用情况和每个容器的运行状态
- 接受来自ApplicationMaster的启动/停止容器的各种请求
需要说明的是,NodeManager主要负责管理抽象的容器,只处理与容器相关的申请,而不是具体负责每个任务(Map任务或Reduce任务)自身状态的管理。因为这些管理工作是由ApplicationMaster完成的,ApplicationMaster会通过不断与NodeManager通信来掌握各个任务的执行状态(NodeManager向ApplicationMaster主动汇报容器中的任务执行到什么状态)。
在集群部署方面,YARN中的各个组件是和Hadoop集群中的其他组件进行统一部署的。
如下图所示,两个"管家"部署在一个节点上。
NodeManager、ApplicationMaster、DataNode也可以一起部署。
NodeManager、Container、DataNode也是一起部署的,因为底层容器属于计算资源,运行在不同的数据节点上。DataNode既作为HDFS数据节点使用,也作为计算节点使用。NodeManager作为代理者,也和他们部署在一起。
7.3.4 YARN工作流程
YARN的工作流程图如下所示:
具体步骤:
- 用户编写客户端应用程序,向YARN提交应用程序,提交的内容包括ApplicationMaster程序、启动ApplicationMaster的命令、用户程序等。
- YARN中的ResourceManager负责接受和处理来自客户端的请求,为应用程序分配一个容器,在该容器中启动一个ApplicationMaster,从而让ApplicationMaster掌管整个作业执行过程。
- ApplicationMaster被创建后会首先向ResourceManager注册,以便ResourceManager对它进行实时监控管理。
- ApplicationMaster采用轮询的方式向ResourceManager申请资源。作业被分解成多个Map任务和Reduce任务,每个任务都需要申请容器以执行任务。
- ResourceManager以"容器"的形式向提出申请的ApplicationMaster分配资源。
- 在容器中启动任务(运行环境、脚本)。ApplicationMaster获得容器后,将资源进行二次分配,分配给自己管辖的Map任务和Reduce任务,分别进行启动执行。启动时,ApplicationMaster会为容器设置好整个应用程序运行环境,包括jar包、环境变量、二进制程序,都整理好发送给程序,并将运行应用程序的命令写作脚本发给容器,容器接受到之后,启动脚本即可完成任务的启动。
- 各个任务向ApplicationMaster汇报自己的状态和进度。每个节点上都驻留着NodeManager组件,作为代理,实时监控容器运行状态,并反馈给ApplicationMaster。
- 应用程序运行完成后,ApplicationMaster向ResourceManager的应用程序管理器注销并关闭自己(释放掉容器资源)。
7.3.5 YARN框架与MapReduce1.0框架的对比分析
从MapReduce1.0框架发展到YARN框架,客户端没有发生变化,其大部分调用API及接口都保持兼容。因此,原来针对Hadoop1.0开发的代码不需要作大的改动,就可以直接放到Hadoop2.0平台上运行。
YARN相对于MapReduce1.0的具体优势如下:
- 大大减少了承担中心服务功能ResourceManager的资源消耗
在1.0体系架构中只有JobTracker作为总管家,负责整个作业的调度、管理、监控、资源调度。
而ResourceManager任务简单,只负责资源管理调度,工作量减轻、资源消耗少。 - ApplicationMaster来完成需要大量资源消耗的任务调度和监控
每一个作业启动时,都会为它分配一个相关联的ApplicationMaster作为管家,管理整个作业的全流程运行。 - 多个作业对应多个ApplicationMaster,实现了监控分布化
多个ApplicationMaster分别管理多个作业的全流程运行。 - MapReduce1.0 既是一个计算框架,又是一个资源管理调度框架。但是,只能支持MapReduce编程模型(只能为MapReduce调度资源,不支持其他任务)。而YARN是一个纯粹的资源调度管理框架,在它上面可以运行包括MapReduce在内的不同类型的计算框架(比如可以运行Storm框架),只要编程实现相应的ApplicationMaster。
这是因为ApplicationMaster是可以替换的模块,在YARN框架中,ApplicationMaster的类型是丰富的,可以针对不同类型的作业设计实现它,从而让它管理各种类型的作业。 - YARN中的资源管理比MapReduce1.0更加高效。以容器为单位,而不是以slot为单位。容器对CPU、内存进行统筹管理,不存在资源空闲但无法使用的问题。
7.3.6 YARN的发展目标
YARN的目标就是实现"一个集群多个框架",为什么?
一个企业当中同时存在各种不同的业务应用场景,需要采用不同的计算框架,而目前都是使用不同的计算框架解决不同的问题,可能涉及到的框架比如:
1.使用MapReduce实现离线批处理
2.使用Impala实现实时交互式查询分箱
3.使用Storm实现流式数据实时分析
4.使用Spark实现迭代计算
这些框架通常来自不同的公式,并且通常带有各自的资源调度管理机制。
如果将这些框架放到一个集群上运行,会出现问题。这些框架的资源管理调度机制不同,会争先抢占底层资源。
因此,为了避免不同类型的应用之间相互干扰,企业需要把内部的服务器拆分成多个集群,分别安装不同的计算框架,即"一个框架一个集群"。
但是这样拆分集群,导致了如下问题:
1.集群资源利用率低:即使某一个集群的资源空闲也不能分配给另一个集群使用,是完全隔离的,资源不能共享。
2.数据无法共享:企业中的数据通常需要经过一种计算框架处理后提交给另一种计算框架处理执行,通过多个计算框架完成一个大的作业。一旦集群隔离,就要通过人工拷贝的方式。底层不共享就只能通过大规模数据传输解决数据共享问题,导致大量数据共享开销。
3.维护代价高:集群是不同的,需要不同的人管理不同的集群。
YARN提出
YARN的目标就是实现"一个集群多个框架",即在一个集群上部署一个统一的资源调度管理框架YARN,在YARN之上可以部署其他各种计算框架。所有计算框架共用YARN的资源调度管理功能。
在底层HDFS基础上搭建YARN框架,由YARN框架为这些计算框架提供统一的资源调度管理服务,并且能够根据各种计算框架的负载需求,调整各自占用的资源,实现集群资源共享和资源弹性收缩。集群资源可以通过YARN进行实时调整,把资源进行合理的调整分配,需求量大就多分配一些。
可以实现一个集群上的不同应用负载混搭,有效提高了集群利用率。
不同计算框架可以共享底层存储,避免了数据跨集群移动。
在YARN上部署各种计算框架示意图如下
底层是HDFS,上面各种计算框架都共享底层HDFS存储。因此进行数据共享交换时可以直接读取底层的存储,不需要再将数据从一个集群传到另一个集群,避免了数据跨集群移动。
一个新的计算框架如何运行在YARN之上?
让YARN中的ApplicationMaster组件重新编写代码,让ApplicationMaster为这个新的计算框架服务即可。
7.4 Hadoop生态系统中具有代表性的功能组件
7.4.1 Pig
Pig是Apache项目中一个开源的项目,而且是整个Hadoop生态系统中的一个组件。
Pig提供了类似SQL的Pig Latin语言(包含Filter、GroupBy、Join、OrderBy等操作,同时也支持用户自定义函数),用户只需要撰写非常简单的Pig Latin语句就可以完成各种复杂的数据分析任务,而不需要编写复杂的MapReduce程序。Pig会自动把用户编写的脚本转换成MapReduce作业在Hadoop集群上运行,而且具备对生成的MapReduce程序进行自动优化的功能。因此,用户编写Pig程序的时候,不需要关心程序的运行效率,这大大减少了用户编程的时间。
Pig提供了过滤、分组、连接、排序等操作,通过Pig Latin语言可以很容易实现。
通过配合使用Pig和Hadoop,在处理海量数据时就可以实现事半功倍的效果,比使用Java、C++等语言编写MapReduce程序的难度要小很多,并且用更少的代码量实现了相同的数据处理分析功能。
Pig可以加载数据、表达转换数据、存储最终结果。
Pig语句通常按照如下格式编写:
- 通过LOAD语句去文件系统读取数据。
- 通过一系列"转换"语句对数据进行处理
- 通过STORE语句把处理结果输出到文件当中去,或者用DUMP语句把处理结果输出到屏幕上面。
在企业中,通常使用Pig进行数据加工(ETL过程),把数据收集后进行处理转换,并将处理结果存储在数据仓库Hive中,让Hive完成海量数据分析。
下面是采用Pig Latin语言编写的应用程序实例,实现了对用户访问网页情况的统计分析:
在Pig Latin中写完代码之后,剩下的事情交给Pig Latin引擎,它会自动把代码转换成底层的MapReduce作业执行。上图中的代码经转换会生成如下流程图,代码被系统转化成了Map任务和Reduce任务。
第一行语句是Load Visits语句,是加载数据,因此转换成Map1任务。
第二行语句是Group By分组任务,需要横跨Map阶段和Reduce阶段。
第三行语句是聚合操作,转换成Reduce1任务。
第四行代码也是加载数据,需要通过Map2任务进行加载。
第五行代码是两表连接,需要横跨Map阶段和Reduce阶段。
注意,矩形框5和矩形框4是有重叠的,这是因为Map2任务把文件加载进来之后,输出了键值对列表,可供5使用。但是矩形框3和矩形框5没有重叠,这是因为3已经完成了Reduce任务,已经把结果写入了HDFS中,不会直接给5。
第六行代码是根据网页内容对连接结果进行分组,需要横跨Map阶段和Reduce阶段。
第七行代码是对分组进行聚合统计,计算每一个分类的访问量。因此转换成Reduce3任务。
Pig的应用场景
Pig是面向技术人员的,并且通常是即时性的数据处理需求,这样可以通过Pig很快写一个脚本开始运行处理,而不需要创建表等相关的事先准备工作。
Pig主要用户
- Yahho!:90%以上的MapReduce作业是Pig生成的。
- Twitter:80%以上的MapReduce作业是Pig生成的。
- Linkedin:大部分的MapReduce作业是Pig生成的。
- 其他主要用户:Salesforce、Nokia、AOL、comScore。
7.4.2 Tez
Tez是Apache开源的支持DAG(有向无环图)作业的框架,它直接源于MapReduce框架。
Tez的核心思想是将Map和Reduce两个操作进行进一步拆分,Map被拆分成Input、Processor、Sort、Merge、Output,Reduce被拆分成Input·、Shuffle、Sort、Merge、Processor和Output等子操作。
分解后的元操作可以进行任意灵活组合,产生新的操作。这些操作经过一些控制程序组装后,可以形成一个大的DAG作业。可以通过DAG作业的方式运行MapReduce作业,提供程序运行的整体处理逻辑。可以去除掉工作流中多余的Map阶段,减少不必要的操作,提高了数据处理的性能。
Hortonworks(一个知名的提供商业版本Hadoop厂家)将Tez应用到了数据仓库Hive的优化中,使得性能提升了约100倍。
HiveQL语句在MapReduce和Tez中的执行情况对比
左侧代码是HiveQL语句,实现了连接分组功能。
这段代码若在数据仓库Hive中执行,Hive提供了自动转化功能,会把这段代码自动转换成底层MapReduce作业,得到左侧的流程图结果,M表示Map任务,R表示Reduce任务,发现要将MapReduce任务写入HDFS文件,涉及了4次MapReduce和3次HDFS,而涉及HDFS的操作都是较为耗时的。
右侧是经过Tez转化得到的流程图,消除了写入HDFS、从HDFS读出等操作,大大提升了性能,即去除了连续两个作业之间的"写入HDFS"。并且,去除了每个工作流中多余的Map阶段。
在Hadoop2.0生态系统中,MapReduce、Hive、Pig等计算框架,都需要最终以MapReduce任务的形式执行数据分析。因此,Tez框架可以发挥重要作用,可以借助Tez框架实现对MapReduce、Pig和Hive等的性能优化。可以解决现有MR框架在迭代计算(如PageRank计算)和交互式计算方面的问题。
Tez框架在Hadoop生态系统中的作用
底层使用HDFS,在HDFS上架构资源管理调度YARN,在YARN之上可以构建Tez框架,由Tez对MR、Pig、Hive和其他计算框架(底层转换成MapReduce作业的计算框架)进行优化。
Tez+Hive与Impala、Dremel和Drill的区别?
复习:Impala是类似Hive的数据仓库,可以提供实时的交互式分析。Drill是谷歌Dremel的开源实现。
Tez在解决Hive、Pig延迟大、性能低等问题的思路,是和那些支持实时交互式查询分析的产品(如Impala、Dremel和Drill)是不同的。
Impala、Dremel和Drill的解决思路是完全抛弃MapReduce计算框架,不再将类似SQL的HiveQL语句或者Pig语句翻译成MapReduce程序,而是采用与商用并行关系数据库类似的分布式查询引擎,可以直接从HDFS或者HBase中用SQL语句查询数据,而不需要把SQL语句转化成MapReduce任务执行,从而大大降低了延迟,很好的满足了实时查询的要求。
Tez则不同,比如针对Hive数据仓库进行优化的"Tez+Hive"解决方案,仍然使用MapReduce计算框架,但是对DAG作业依赖关系进行了裁剪,并且将多个小作业合并成一个大作业。这样不仅计算量减少了,而且写HDFS次数也会大大减少。
7.4.3 Spark
Hadoop缺陷:
- 其MapReduce计算模型延迟过高,无法胜任实时、快速计算的需求,因此只适用于离线批处理的应用场景。
- 中间结果写入磁盘,每次运行都从磁盘读数据。
- 在前一个任务执行完成之前,其他任务无法开始,难以胜任复杂、多阶段的计算任务。
Spark最初诞生于伯克利大学的APM实验室,是一个可以应用于大规模数据处理的快速、通用引擎,如今是Apache软件基金会下的顶级开源项目之一。
Spark在借鉴Hadoop MapReduce优点的同时,很好的解决了MapReduce所面临的问题:
- Spark采用内存计算,不需要使用磁盘,带来了更高的迭代运算效率。
- 基于DAG的任务调度执行机制,优于MapReduce的迭代执行机制。
当前,Spark正在以其结构一体化、功能多元化的趋势,逐渐成为当今大数据领域最热门的大数据计算平台。
7.4.4 Kafka
Kafka是一 种高吞吐量的分布式发布订阅消息系统,用户通过Kafka系统可以发布大量的消息,同时也能实时订阅消费消息。
Kafka可以同时满足在线实时处理和批量离线处理。
Kafka作为数据交换枢纽
Kafka要在企业构建大数据系统中,起到数据交换中枢的作用。在企业中,使用一种产品满足所有业务需求是不可能的,为了满足不同业务需求,需要引入不同的有某方面特长的系统。实际当中不可能为每个分布系统开发一个专门的与Hadoop交互的工具,只设计针对Kafka的交互工具即可。
不同类型的分布系统(关系数据库、NoSQL数据库、流处理系统、批处理系统等),可以统一接入到Kafka,实现和Hadoop各个组件之间的不同类型数据的实时高效交换。