Apache Spark学习

关于Apache Spark

1. 2003-2006年,谷歌发表了Google filesystem、MapReduce、bigtable三篇重量级系统论文,分别讨论了大规模数据如何存储、处理及结构化组织。之后Apache Hadoop社区对这些论文进行了开源实现,开发了hdf分布式文件系统、Hadoop MapReduce大数据处理框架和HBase分布式key-value数据库,大大降低了大数据应用开发、运行及数据存储管理的难度。
2. MapReduce成功将函数式编程思想引入分布式数据处理中,仅仅用练个函数map()和reduce()就解决了一大类的大数据处理问题,而且不要求用户熟悉分布式文件系统。随着大数据应用越来越多,处理性能的要求越来越高,MapReduce的一些缺点也显现出来。如MapReduce编程模型的表达能力较弱,仅使用map和reduce两个函数难以实现复杂的数据操作;处理流程固定,不容易实现迭代计算;基于磁盘进行数据传递,效率较低。这些缺点导致使用MapReduce开发效率较低、执行复杂的数据处理任务的性能也不高。
3. 2008-2009年微软研发了dryad/dryadLINQ,其中dryad类似MapReduce,但以有向无环图DAG(directed acycline graph)形势的数据流代替了map-reduce两阶段数据流,处理流程更通用,支持复杂的数据处理任务。dryadLINQ为dryad提供了高层编程语言,将更多的函数式编程思想(来源于C#的LINQ)引入编程模型中,表达能力更强,如容易实现join()等操作。由于dryad/dryadLINQ在当时没有开源,所以没有得到大规模使用。
4. 2012年,UCBerkeley的AMPLab研发并开源了新的大数据处理框架spark。核心思想包括两方面:一方面对大数据处理框架的输入输出、中间数据进行建模,将这些数据抽象为统一的数据结构,命名为弹性分布式数据集RDD(resilient distributed dataset),并在次数据结构上构建了一系列通用的数据操作,使得用户可以简单地实现复杂的数据处理流程;另一方面采用基于内存的数据聚合、数据缓存等机制来加速应用执行,尤其适用于迭代和交互式应用。spark采用EPFL大学研发的函数式编程语言Scala实现,并且提供了Scala、Java、Python、R四种语言的接口,以方便开发着使用熟悉的语言进行大数据应用开发。
5. 经过多年发展,spark也与Hadoop一样构建了完整的生态系统。Apache spark生态系统以spark处理框架为核心,在上层构建了面向SQL语言的spark SQL框架、面向大规模图计算的graphX框架、面向大规模机器学习的MLlib框架及算法库,以及面向流处理的spark streaming框架;在下层,spark及其关联社区也推出了相关存储系统,如基于内存的分布式文件系统Alluxio、支持ACID事务的数据湖系统delta lake等。

大数据处理框架概览

1. 大数据具有数据量大(volume)、数据类型多样性(variety)、产生与处理速度快(velocity)、价值高(value)的4V特性。虽然关系型数据库解决了关系型数据的存储与OLTP(online transaction processing 在线事务处理)问题,数据仓库解决了数据建模及OLAP(online analytical processing 在线分析处理)问题。但在大数据环境下,传统的数据库和数据仓库都面临着可扩展性的问题。为了解决这个问题,多种可扩展的大数据处理框架应运而生。
2. 2004年Google提出了基于分治、归并和函数式编程思想的MapReduce分布式计算框架。随后Apache社区对Google file system和MapReduce进行了开源实现,命名为Hadoop。2007年微软提出了dryad分布式计算框架,允许用户将任务处理组织成有向无环图DAG,来获得更强的数据处理能力。2012年UC Berkeley的AMPLab提出了基于内存,适合迭代计算的spark分布式处理框架。该框架允许用户将可重用的数据缓存到内存中,同时利用内存进行中间数据的聚合,极大缩短了数据处理的时间。这些大数据框架拥有共同的编程模型,即MapReduce-like模型,采用“分治——聚合”策略来对大数据进行分布并行处理。
3. 大数据应用有很多配置参数。一类是与资源相关的配置参数, 在Hadoop中,MapReduce任务实际启动一个JVM来运行,因此用户可以设置JVM大小,也就是heap size。在spark中,MapReduce任务在资源容器(executor JVM)中以线程的方式执行,用户需要估算应用的资源需求量,并设置应用需要的资源容器个数、CPU个数和内存大小。另一类是与数据流相关的配置参数。 如Hadoop和spark中都可以设置partition()函数、partition个数和数据分块大小。partition函数定义如何划分map()的输出数据。partition个数定义产生多少个数据分块,也就是有多少个reduce任务会被运行。数据分块大小定义map任务的输入数据大小。
4. 由于Hadoop/spark框架本身没有提供自动优化配置参数的功能,starFish研究了如何选择性能最优的Hadoop应用配置参数,其核心是一个Just-In-Time的优化器,该优化器可以对Hadoop应用的历史运行信息进行分析,并根据分析结果来预测应用在不同配置参数下的执行时间,以选择最优参数。
5. MapReduce具有固定的执行流程(map-shuffle-reduce),可以直接将包含map/reduce函数的作业划分为map和reduce两个阶段。map阶段包含多个可以并行执行的map任务,reduce阶段包含多个可以并行执行的reduce任务。map任务负责将输入的分块数据进行map处理,并将其输出结果写入缓冲区,然后对缓冲区中的数据进行分区、排序、聚合等操作,最后将数据输出到磁盘上的不同分区中。reduce任务首先将map任务输出的对应分区数据通过网络传输拷贝到本地内存中,内存空间不够时,会将内存数据排序后写入磁盘,然后通过归并、排序等阶段产生reduce的输入数据。reduce处理完输入数据后,将输出数据写入分布式文件系统汇总。
6. spark应用的转化过程包含两层:逻辑处理流程、执行阶段与执行任务划分。spark首先根据用户代码中的数据操作语义和操作顺序,将代码转化为逻辑处理流程。逻辑处理流程包含多个数据单元和数据依赖,每个数据单元包含多个数据分块。然后框架对逻辑处理流程进行划分,生成物理执行计划。该计划包含多个执行阶段stage,每个执行阶段包含若干执行任务task。微软的大数据编程框架dryadLINQ也提供类似的编译过程,可以将用户编写的大数据应用程序LINQ编译为可分布运行的dryad执行计划和任务。
7. 为了将用户代码转化为逻辑处理流程,spark和dryad对输入输出、中间数据进行了更具体的抽象处理,将这些数据用一个统一的数据结构表示。在spark中,输入输出、中间数据被表示成RDD。在RDD上可以执行多种数据操作,如简单的map以及复杂的cogroup、join等。一个RDD可以包含多个数据分区partition。parentRDD和childRDD之间通过数据依赖关系关联,支持一对一和多对一等数据依赖关系。数据依赖关系的类型由数据操作的类型决定。逻辑处理流程是一个有向无环图DAG。
8. 为了将逻辑处理流程转化为物理执行计划,spark首先根据RDD之间的数据依赖关系,将整个流程划分为多个小的执行阶段stage。之后,在每个执行阶段形成计算任务task,计算任务的个数一般与RDD中分区的个数一致。与MapReduce不同的是,一个sparkjob可以包含很多个执行阶段,而且每个执行阶段可以包含多种计算任务,因此并不能严格地区分每个执行阶段中的任务是map任务还是reduce任务。另外在spark中,用户可以通过cache接口使框架缓存可被重用的中间数据。例如当前job的输出可能会被下一个job用到,那么用户可以使用cache对这些数据进行缓存。
9. 从系统架构上讲,大数据处理框架一般是主-从结构master-worker。主节点负责接收用户提交的应用,处理请求,管理应用运行的整个生命周期。从节点负责执行具体的数据处理任务task,并在运行过程中向主节点汇报任务的执行状态。
10. spark支持不同的部署模式,如standalone部署模式、on yarn模式和mesos模式等。关于standalone模式,Hadoop MapReduce是为每个task启动一个JVM进程运行,而且是在task将要运行时启动JVM,而spark是预先启动资源容器executor JVM,然后当需要执行task时,再在executor JVM里启动task线程运行。
11. 任务调度器包含先进先出FIFO调度器、公平fair调度器等。任务调度的主要目的是通过设置不同的策略来决定应用或任务获得资源的先后顺序。
12. 在Hadoop MapReduce中,一个应用需要经历map、shuffle、reduce3个数据处理阶段。在spark中,一个应用可以有更多的执行阶段stage,如迭代型应用可能有几十个执行阶段,每个执行阶段也包含多个task。另外,这些执行阶段可以形成复杂的DAG图结构。在物理执行时先执行上游stage中的task,完成后执行下游stage中的task。
13. 在Hadoop MapReduce中,每个task对应一个进程,也就是说每个task以JVM的方式来运行,所以在Hadoop MapReduce中task的内存用量指的是JVM的堆内存用量。在spark中,每个task对应JVM中的一个线程,而一个JVM可能同时运行了多个task,因此JVM的内存空间由task共享。在应用未运行前,我们难以预知task的内存消耗和执行时间,也难以预知JVM中的堆内存用量。
14. 从应用特点来分析,task执行过程中主要消耗内存的数据分为三类:
    (1)框架执行时的中间数据。例如,map输出到缓冲区的数据和reduce task在shuffle阶段暂存到内存中的数据。    
    (2)框架缓存数据。例如,在spark中,用户调用cache接口缓存到内存中的数据。
    (3)用户代码产生的中间计算结果。例如用户代码调用map、reduce、combine,在处理输入数据时会在内存中产生中间计算结果。

其他大数据处理框架

1. 除了上述的分布式处理框架MapReduce、spark和dryad,Yahoo还提出了MapReduce merge框架,通过在reduce阶段后面加入merge阶段,提高了MapReduce对二维表的关系代数处理能力。UC Berkeley提出了MapReduce online,改进了从map阶段到reduce阶段的数据流动方式,使得mapper输出的数据可以更快地流入reducer中,提高MapReduce对数据的在线处理能力。UCI的Bu等提出了HaLoop,提高了MapReduce迭代型任务的执行性能。NYU提出的面向内存计算应用的分布式计算编程模型piccolo可以提供key-value表的操作接口。与MapReduce相比,piccolo能够轻松地访问中间状态及中间数据。spark structured streaming和Apache Flink统一了批处理与流处理的执行流程。
2. spark除了支持基本的RDD数据结构,还支持在RDD基础上扩展的、面向结构化数据的高级数据结构(主要是表格数据),即dataset和dataframe。使用dataset、dataframe开发的应用可以更好地执行各种SQL操作,并利用sparkSQL引擎中的优化技术来对执行计划进行优化。可参考spark SQL论文哈《spark SQL内核剖析》学习sparkSQL引擎汇总的优化技术。

Spark系统部署与应用运行的基本流程

posted on 2023-03-17 17:28  张少凯  阅读(39)  评论(0编辑  收藏  举报

导航