spark原理及工作流程

1.1spark简介

1、Spark 是什么

Spark 是基于内存计算的大数据并行计算框架。Spark基于内存计算,提高了在大数据环境下数据处理的实时性,同时保证了高容错性和高可伸缩性,允许用户将Spark部署在大量廉价硬件之上,形成集群。

AMPLab 开发以Spark 为核心的BDAS 时提出的目标是:one stackto rule them all,也就是说在一套软件栈内完成各种大数据分析任务。相对于MapReduce上的批量计算、迭代型计算以及基于Hive的SQL 查询,Spark 可以带来上百倍的性能提升。目前Spark 的生态系统日趋完善,Spark SQL的发布、Hive onSpark 项目的启动以及大量大数据公司对Spark全栈的支持,让Spark 的数据分析范式更加丰富。

2、Spark 相比Hadoop MapReduce 的优势一如下。

(1)中间结果输出

基于MapReduce 的计算引擎通常会将中间结果输出到磁盘上,进行存储和容错。出于任务管道承接的考虑,当一些查询翻译到MapReduce任务时,往往会产生多个Stage,而这些串联的Stage 又依赖于底层文件系统(如HDFS)来存储每一个Stage 的输出结果。Spark 将执行模型抽象为通用的有向无环图执行计划(DAG),这可以将多Stage 的任务串联或者并行执行,而无须将Stage 中间结果输出到HDFS 中。类似的引擎包括Dryad、Tez。

(2)数据格式和内存布局

由于MapReduce Schema on Read 处理方式会引起较大的处理开销。Spark 抽象出分布式内存存储结构弹性分布式数据集RDD,进行数据的存储。RDD 能支持粗粒度写操作,但对于读取操作,RDD 可以精确到每条记录,这使得RDD 可以用来作为分布式索引。Spark的特性是能够控制数据在不同节点上的分区,用户可以自定义分区策略,如Hash分区等。Shark 和Spark SQL 在Spark 的基础之上实现了列存储和列存储压缩。

(3)执行策略

MapReduce 在数据Shuffle 之前花费了大量的时间来排序,Spark 则可减轻上述问题带来的开销。因为Spark 任务在Shuffle 中不是所有情景都需要排序,所以支持基于Hash的分布式聚合,调度中采用更为通用的任务执行计划图(DAG),每一轮次的输出结果在内存缓存。

(4)任务调度的开销

传统的MapReduce 系统,如Hadoop,是为了运行长达数小时的批量作业而设计的,在某些极端情况下,提交一个任务的延迟非常高。

Spark 采用了事件驱动的类库AKKA 来启动任务,通过线程池复用线程来避免进程或线程启动和切换开销。

3、Spark 的一站式解决方案有很多的优势,具体如下。

(1)打造全栈多计算范式的高效数据流水线

Spark 支持复杂查询。在简单的map及reduce操作之外,Spark 还支持SQL 查询、流式计算、机器学习和图算法。同时,用户可以在同一个工作流中无缝搭配这些计算范式。

(2)轻量级快速处理

Spark 1.0 核心代码只有4 万行。这是由于Scala 语言的简洁和丰富的表达力,以及Spark 充分利用和集成Hadoop 等其他第三方组件,同时着眼于大数据处理,数据处理速度是至关重要的,Spark通过将中间结果缓存在内存减少磁盘I/O来达到性能的提升。

(3)易于使用,Spark支持多语言

Spark 支持通过Scala、Java 及Python 编写程序,这允许开发者在自己熟悉的语言环境下进行工作。它自带了80多个算子,同时允许在Shell中进行交互式计算。用户可以利用Spark像书写单机程序一样书写分布式程序,轻松利用Spark搭建大数据内存计算平台并充分利用内存计算,实现海量数据的实时处理。

(4)与HDFS等存储层兼容

Spark可以独立运行,除了可以运行在当下的YARN 等集群管理系统之外,它还可以读取已有的任何Hadoop数据。这是个非常大的优势,它可以运行在任何Hadoop数据源上,如Hive、HBase、HDFS 等。这个特性让用户可以轻易迁移已有的持久化层数据。

4、spark的缺点

同时我们也应该看到Spark 并不是完美的,RDD 模型适合的是粗粒度的全局数据并行计算。不适合细粒度的、需要异步更新的计算。对于一些计算需求,如果要针对特定工作负载达到最优性能,还是需要使用一些其他的大数据系统。例如,图计算领域的GraphLab在特定计算负载性能上优于GraphX,流计算中的Storm 在实时性要求很高的场合要比SparkStreaming 更胜一筹。

1.2 Spark 生态系统BDAS

目前,Spark 已经发展成为包含众多子项目的大数据计算平台。伯克利将Spark 的整个生态系统称为伯克利数据分析栈(BDAS)。其核心框架是Spark,同时BDAS 涵盖支持结构化数据SQL 查询与分析的查询引擎Spark SQL和Shark,提供机器学习功能的系统MLbase 及底层的分布式机器学习库MLlib、并行图计算框架GraphX、流计算框架SparkStreaming、采样近似计算查询引擎BlinkDB、内存分布式文件系统Tachyon、资源管理框架Mesos 等子项目。这些子项目在Spark 上层提供了更高层、更丰富的计算范式。

图1-1 为BDAS的项目结构图。

 

下面对BDAS 的各个子项目进行更详细的介绍。

(1)Spark

Spark 是整个BDAS 的核心组件,是一个大数据分布式编程框架,不仅实现了MapReduce的算子map 函数和reduce 函数及计算模型,还提供更为丰富的算子,如filter、join、groupByKey 等。Spark 将分布式数据抽象为弹性分布式数据集(RDD),实现了应用任务调度、RPC、序列化和压缩,并为运行在其上的上层组件提供API。其底层采用Scala这种函数式语言书写而成,并且所提供的API 深度借鉴Scala 函数式的编程思想,提供与Scala 类似的编程接口。 图1-2 为Spark 的处理流程(主要对象为RDD)。

Spark 将数据在分布式环境下分区,然后将作业转化为有向无环图(DAG),并分阶段进行DAG 的调度和任务的分布式并行处理。

(2)Shark

Shark 是构建在Spark 和Hive 基础之上的数据仓库。目前,Shark 已经完成学术使命,终止开发,但其架构和原理仍具有借鉴意义。它提供了能够查询Hive中所存储数据的一套SQL接口,兼容现有的HiveQL 语法。这样,熟悉HiveQL 或者SQL 的用户可以基于Shark 进行快速的Ad-Hoc、Reporting 等类型的SQL 查询。Shark 底层复用Hive 的解析器、优化器以及元数据存储和序列化接口。Shark会将Hive QL 编译转化为一组Spark 任务,进行分布式运算。

(3)SparkSQL

Spark SQL 提供在大数据上的SQL 查询功能,类似于Shark 在整个生态系统的角色,它们可以统称为SQL onSpark。之前,Shark的查询编译和优化器依赖于Hive,使得Shark不得不维护一套Hive 分支,而Spark SQL使用Catalyst 做查询解析和优化器,并在底层使用Spark 作为执行引擎实现SQL 的Operator。用户可以在Spark 上直接书写SQL,相当于为Spark 扩充了一套SQL 算子,这无疑更加丰富了Spark 的算子和功能,同时Spark SQL不断兼容不同的持久化存储(如HDFS、Hive 等),为其发展奠定广阔的空间。

(4)SparkStreaming

Spark Streaming 通过将流数据按指定时间片累积为RDD,然后将每个RDD 进行批处理,进而实现大规模的流数据处理。其吞吐量能够超越现有主流流处理框架Storm,并提供丰富的API 用于流数据计算。

(5)GraphX

GraphX 基于BSP 模型,在Spark 之上封装类似Pregel 的接口,进行大规模同步全局的图计算,尤其是当用户进行多轮迭代时,基于Spark内存计算的优势尤为明显。

(6)Tachyon

Tachyon 是一个分布式内存文件系统,可以理解为内存中的HDFS。为了提供更高的性能,将数据存储剥离Java Heap。用户可以基于Tachyon 实现RDD 或者文件的跨应用共享,并提供高容错机制,保证数据的可靠性。

(7)Mesos

Mesos 是一个资源管理框架一,提供类似于YARN 的功能。用户可以在其中插件式地运行Spark、MapReduce、Tez 等计算框架的任务。Mesos 会对资源和任务进行隔离,并实现高效的资源任务调度。

(8)BlinkDB

BlinkDB 是一个用于在海量数据上进行交互式 SQL 的近似查询引擎。它允许用户通过在查询准确性和查询响应时间之间做出权衡,完成近似查询。其数据的精度被控制在允许的误差范围内。为了达到这个目标,BlinkDB的核心思想是:通过一个自适应优化框架,随着时间的推移,从原始数据建立并维护一组多维样本;通过一个动态样本选择策略,选择一个适当大小的示例,然后基于查询的准确性和响应时间满足用户查询需求。

1.3 Spark 架构

Spark 是整个BDAS 的核心。生态系统中的各个组件通过Spark来实现对分布式并行任务处理的程序支持。

1.Spark 的代码结构

图1-3 展示了Spark-1.0的代码结构和代码量(不包含Test和Sample 代码),读者可以通过代码架构对 Spark 的整体组件有一个初步了解,正是这些代码模块构成了Spark架构中的各个组件,同时读者可以通过代码模块的脉络阅读与剖析源码,这对于了解Spark的架构和实现细节都是很有帮助的。下面对图1-3中的各模块进行简要介绍。

scheduler:文件夹中含有负责整体的Spark 应用、任务调度的代码。

broadcast:含有Broadcast(广播变量)的实现代码,API 中是Java 和Python API 的 。

deploy:含有Spark 部署与启动运行的代码。

common:不是一个文件夹,而是代表Spark 通用的类和逻辑实现,有5000 行代码。

metrics:是运行时状态监控逻辑代码,Executor 中含有Worker 节点负责计算的逻辑码。

partial:含有近似评估代码。

network:含有集群通信模块代码。

serializer:含有序列化模块的代码。

storage:含有存储模块的代码。

ui :含有监控界面的代码逻辑。其他的代码模块分别是对Spark生态系统中其他组件的实现。

streaming:是Spark Streaming的实现代码。

YARN:是Spark onYARN 的部分实现代码。

graphx:含有GraphX 实现代码。

interpreter:代码交互式Shell 的代码量为3300 行。

mllib:代表MLlib 算法实现的代码量。

sql 代表Spark SQL的代码量。

2.Spark 的架构

Spark 架构采用了分布式计算中的Master-Slave模型。Master 是对应集群中的含有Master 进程的节点,Slave 是集群中含有Worker 进程的节点。Master 作为整个集群的控制器,负责整个集群的正常运行;Worker相当于是计算节点,接收主节点命令与进行状态汇报;Executor负责任务的执行;Client作为用户的客户端负责提交应用,Driver负责控制一个应用的执行,如图1-4所示。

 

Spark 集群部署后,需要在主节点和从节点分别启动Master进程和Worker 进程,对整个集群进行控制。在一个Spark 应用的执行过程中,Driver Worker 是两个重要角色。Driver 程序是应用逻辑执行的起点,负责作业的调度,即Task任务的分发,而多个Worker用来管理计算节点和创建Executor 并行处理任务。在执行阶段,Driver 会将Task Task所依赖的file jar 序列化后传递给对应的Worker 机器,同时Executor 对相应数据分区的任务进行处理。

 

下面详细介绍Spark 的架构中的基本组件。

­ ClusterManager :在Standalone 模式中即为Master(主节点),控制整个集群,监控Worker。在YARN 模式中为资源管理器。

­ Worker :从节点,负责控制计算节点,启动 Executor或 Driver。在 YARN 模式中为NodeManager,负责计算节点的控制。

­ Driver:运行Application 的main() 函数并创建SparkContext。

­ Executor :执行器,在 workernode 上执行任务的组件、用于启动线程池运行任务。每个Application拥有独立的一组Executors。

­ SparkContext:整个应用的上下文,控制应用的生命周期。

­ RDD:Spark 的基本计算单元,一组 RDD 可形成执行的有向无环图 RDDGraph。

­ DAG Scheduler:根据作业Job构建基于Stage的DAG,并提交Stage给TaskScheduler。

­ TaskScheduler:将任务(Task)分发给 Executor执行。

­ SparkEnv:线程级别的上下文,存储运行时的重要组件的引用。SparkEnv内创建并包含如下一些重要组件的引用。

­ MapOutPutTracker:负责 Shuffle 元信息的存储。

­ BroadcastManager:负责广播变量的控制与元信息的存储。

­ BlockManager:负责存储管理、创建和查找块。

­ MetricsSystem:监控运行时性能指标信息。

­ SparkConf:负责存储配置信息。

Spark 的整体流程为:Client 提交应用,Master 找到一个Worker 启动Driver,Driver 向Master 或者资源管理器申请资源,之后将应用转化为RDDGraph,再由DAGScheduler将RDD Graph转化为Stage 的有向无环图提交给TaskScheduler,由TaskScheduler提交任务给Executor 执行。在任务执行的过程中,其他组件协同工作,确保整个应用顺利执行。

3.Spark 运行逻辑

如图1-5 所示,在Spark 应用中,整个执行流程在逻辑上会形成有向无环图(DAG)。Action 算子触发之后,将所有累积的算子形成一个有向无环图,然后由调度器调度该图上的任务进行运算。Spark的调度方式与MapReduce有所不同。Spark 根据RDD 之间不同的依赖关系切分形成不同的阶段(Stage),一个阶段包含一系列函数执行流水线。图中的A、B、C、D、E、F 分别代表不同的RDD,RDD 内的方框代表分区。数据从HDFS 输入Spark,形成RDD A 和RDD C,RDD C 上执行map 操作,转换为RDD D, RDD B 和 RDDE 执行join 操作,转换为F,而在B 和E 连接转化为F 的过程中又会执行Shuffle,最后RDD F 通过函数saveAsSequenceFile输出并保存到HDFS中。

你可能感兴趣的:(spark,大数据)