Spark生态系统目前已经很是成熟了,有不少类型的任务均可以使用spark完成,咱们先看下spark生态系统的组成:java
spark的核心主要由3个模块组成:node
(1)spark core 是spark的最底层的编程实现,定义了许多的函数及方法,是全部spark组件的基础依赖sql
(2)spark ecosystems 是spark里面的一些高级组件,基本就是咱们最经常使用的框架apache
(3)resource management 负责spark任务的调度编程
平时咱们开发过程当中,基本上使用的都是第二层里面的一些框架,这里面使用最多的莫过于spark sql和spark streaming了。在对spark整个生态系统有一个基本了解后,下面咱们就关注的是其运行机制了,只有解了运行机制,才会对咱们使用程序,或者排查问题以及性能调优起到很大的帮助。session
下面咱们看下spark任务的运行机制以下图:框架
Spark相关一些术语解释:分布式
(一)Driver program函数
driver就是咱们编写的spark应用程序,用来建立sparkcontext或者sparksession,driver会和cluster mananer通讯,并分配task到executor上执行性能
(二)Cluster Manager
负责整个程序的资源调度,目前的主要调度器有:
YARN
Spark Standalone
Mesos
(三)Executors
Executors实际上是一个独立的JVM进程,在每一个工做节点上会起一个,主要用来执行task,一个executor内,能够同时并行的执行多个task。
(四)Job
Job是用户程序一个完整的处理流程,是逻辑的叫法。
(五)Stage
一个Job能够包含多个Stage,Stage之间是串行的,State的触发是由一些shuffle,reduceBy,save动做产生的
(六)Task
一个Stage能够包含多个task,好比sc.textFile("/xxxx").map().filter(),其中map和filter就分别是一个task。每一个task的输出就是下一个task的输出。
(七)Partition
partition是spark里面数据源的一部分,一个完整的数据源会被spark切分红多个partition以方便spark能够发送到多个executor上去并行执行任务。
(八)RDD
RDD是分布式弹性数据集,在spark里面一个数据源就能够当作是一个大的RDD,RDD由多个partition组成,spark加载的数据就会被存在RDD里面,固然在RDD内部实际上是切成多个partition了。
那么问题来了一个spark job是如何执行的?
(1)咱们写好的spark程序,也称驱动程序,会向Cluster Manager提交一个job
(2)Cluster Manager会检查数据本地行并寻找一个最合适的节点来调度任务
(3)job会被拆分红不一样stage,每一个stage又会被拆分红多个task
(4)驱动程序发送task到executor上执行任务
(5)驱动程序会跟踪每一个task的执行状况,并更新到master node节点上,这一点咱们能够在spark master UI上进行查看
(6)job完成,全部节点的数据会被最终再次聚合到master节点上,包含了平均耗时,最大耗时,中位数等等指标。
最后关于spark的并行执行策略在总结下:
首先咱们的数据源会被加载到RDD里面,在RDD里面整个数据源会被切分红多个partition,partition的个数实际就是咱们执行任务的最大并行度,每一个task会负责一个partition的数据,而每一个spark任务最大能够执行task的个数=executor的个数 * 每一个executor的cores的个数。对应到submit脚本中参数就是:
--num-executors --executor-cores
根据spark官网的建议每一个executor上建议分配置的core的个数应该在3到5之间,若是分配的太多会生成大量的小task执行,task的序列化和传输都会比较耗性能,若是分配的task数量太少,那么咱们的executor大部分时候机器资源就会浪费,因此分配的个数通常在3到5个就行,这一点须要注意。
附录:
Spark中RDD,DataFrame,DataSet的区别:
一、RDD支持面向java、scala对象,编译时强类型检查。缺点,序列化很是消耗时间(集群分发和磁盘存储),不能充分利用系统的高级优化能力(如off-heap),垃圾回收对象开销大。
二、DataFrame支持数据集的模式表示(即数据列的概念),因此集群分发数据时并不须要序列化,能充分利用系统高级优化能力(off-heap),引入查询计划提升性能。缺点,DataFrame的列类型,在编译时没法判断类型,会产生运行时错误。
三、Dataset即支持数据集的模式表示,又支持java、scala对象的类型检查能力。二者经过引入一种编码、解码机制来实现。
参考连接:
http://datastrophic.io/core-concepts-architecture-and-internals-of-apache-spark/
http://backtobazics.com/big-data/spark/understanding-apache-spark-architecture/
https://www.dezyre.com/article/how-data-partitioning-in-spark-helps-achieve-more-parallelism/297
http://www.agildata.com/apache-spark-rdd-vs-dataframe-vs-dataset/