Spark的运行模式

Spark是新一代基于内存的计算框架,是用于大规模数据处理的同意分析引擎。相比于Hadoop MapReduce计算框架,Spark将中间计算结果保留在内存中,速度提升10~100倍;同时采用弹性分布式数据集(RDD)实现迭代计算,更好的适用于数据挖掘、机器学习,极大的提升开发效率。

Spark的运行模式,它不仅支持单机模式,同时支持集群模式运行;这里具体的总结一下Spark的各种运行模式的区分。

Local模式

Local模式又称本地模式,通过Local模式运行非常简单,只需要把Spark的安装包解压后,改一些常用的配置即可使用,而不用启动Spark的Master、Worker进程(只有集群的Standalone模式运行时,才需要这两个角色),也不用启动Hadoop的服务,除非你需要用到HDFS。

运行实例

1
2
3
4
5
6
7
8
9
./bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master local[2] \
lib/spark-examples-1.0.0-hadoop2.2.0.jar \
100

# 1)--master local 就可以确定是单机的local模式了,[2]意思是分配2个cores运行
# 2)--lib/spark-examples-1.0.0-hadoop2.2.0.jar:jar包的路径(application-jar)
# 3)--100:传递给主类的主要方法的可选参数(application-arguments)

这里的spark-submit进程既是客户端提交任务的Client进程,又是Spark的Driver程序,还充当着Spark执行Task的Executor角色。所有的程序都运行在一个JVM中,主要用于开发时测试。

本地伪集群运行模式(单机模拟集群)

这种模式,和Local[N]很像,不同的是它会在单机的环境下启动多个进程来模拟集群下的分布式场景,而不像Local[N]这种多个线程只能在一个进程下委曲求全的共享资源。通常也是用来验证开发出来的应用程序逻辑上有没有出现问题,或者想使用Spark计算框架而没有太多资源的情况下。

运行实例

1
2
3
4
./bin/spark-submit \
--master local-cluster[2,3,1024]

# --master local-cluster[2,3,1024]:在本地模拟集群下使用2个Executor进程,每个进程分配3个cores和1024M的内存来运行程序

这里的spark-submit依然充当全能角色,又是Client进程,又是Driver程序,也负责资源管理。运行该模式很简单,只需要把Spark安装包解压后,修改一些常用的配置,不用启动Spark的Master、Worker守护进程,也不用启动Hadoop的服务,除非你是需要用到HDFS。

Standalone模式(集群)

Standalone是集群模式,这里就需要在执行应用程序前,先启动Spark的Master和Worker守护进程,不用启动Hadoop的服务,除非你需要使用HDFS。

运行实例

1
2
3
4
5
6
7
8
9
10
11
./bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master spark://207.184.161.138:7077 \
--executor-memory 8G \
--total-executor-cores 10 \
/path/to/examples.jar \
1000

# 1) --master spark://207.184.161.138:7077:采用Standalone模式运行,后面是集群地址和端口
# 2) --executor-memory 20G:配置executor进程内存为8G
# 3)--total-executor-cores 100:配置cores数为10个

Master进程作为cluster manager,用来对应用程序申请的资源进行管理;spark-submit做为Client端和运行Driver程序。Standalone模式是Spark实现的资源调度框架,其主要的节点有Client节点,Master节点和Worker节点。其中Driver既可以运行在Master节点上,也可以运行在本地的Client端。

当用spark-shell交互式工具提交Spark的Job时,Driver在Master节点上运行;当使用spark-submit工具提交Job或者在Eclipse、IDEA等开发平台上使用new SparkConf.setManager("spark://master:7077")方式运行Spark任务时,Driver是运行在本地Client端上的。

运行流程

  • SparkContext连接到Master,向Master注册并申请资源(CPU Core和Memory)
  • Master根据SparkContext的资源申请要求和Worker心跳周期内报告的信息决定在哪个Worker上分配资源,然后在该Worker上获取资源,然后启动StandaloneExecutorBackend
  • StandaloneExecutorBackend向SparkContext注册
  • SparkContext将Application代码发给StandaloneExecutorBackend;并且SparkContext解析Application代码,构建DAG图,提交给DAG Scheduler分解成Stage(当碰到Action操作时,就会产生Job;每个Job中含有一个或多个Stage,Stage一般在获取外部数据和shuffle之前产生),然后Stage(又称为TaskSet)提交Task Scheduler,负责将Task分配到相应的Worker,最后提交给StandaloneExecutorBackend执行
  • StandaloneExecutorBackend会构建Executor线程池,开始执行Task,并向SparkContext报告,直至Task完成
  • 所有Task完成后,SparkContext向Master注销,释放资源

on yarn client模式(集群)

越来越多的场景,都是Spark跑在Hadoop集群中,所以为了做到资源能够均衡调度,会使用YARN来做为Spark的Cluster Manager,来为Spark的应用程序分配资源。

运行实例

1
2
3
4
5
6
7
8
./bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode client \
lib/spark-examples-1.0.0-hadoop2.2.0.jar

# 1) --master yarn:采用yarn进行资源调度
# 2) --deploy-mode client:client环境运行

在执行Spark应用程序前,要启动Hadoop的各种服务,由于已经有了资源管理器,所以不需要启动Spark的Master,Worker守护进程。

运行流程

  • Spark Yarn Client向Yarn的ResourceManager申请启动Application Master,同时在SparkContext初始化中创建DAG Scheduler和Task Scheduler,由于我们选择是Yarn Client模式,程序会选择启动YarnClientClusterScheduler和YarnClientSchedulerBackend
  • ResourceManager收到请求后,在集群中选择一个NodeManager,为该应用程序分配第一个Container,要求它在这个Container中启动应用程序的ApplicationMaster;与YarnCluster区别是在该ApplicationMaster中不运行SparkContext,只与SparkContext进行联系进行资源的分配
  • Client中的SparkContext初始化完成后,与ApplicationMaster建立通讯,向ResourceManager注册,根据任务信息向ResourceManager申请资源(Container)
  • 一旦ApplicationMaster申请到资源(也就是Container)后,便于对应的NodeManager通信,要求它在获得的Container中开始向SparkContext注册并申请执行Task任务
  • Client中的SparkContext分配给Container的Task开始执行,并向Driver汇报运行的状态和进度,让Client随时掌握各个任务的运行状态,从而可以在任务失败时重启任务
  • 应用程序完成后,Client的SparkContext向ResourceManager申请注销并关闭自己

on yarn cluster模式(集群)

运行实例

1
2
3
4
5
6
7
8
9
10
./bin/spark-submit --class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode cluster \
--driver-memory 4g \
--executor-memory 2g \
--executor-cores 1 \
examples/jars/spark-examples*.jar \
10

# --driver-memory 4g:集群模式下Yarn Application Master的内存大小

运行流程

  • SparkYarnClient向YARN中ResourceManager提交应用程序,包括ApplicationMaster程序、启动ApplicationMaster的命令、需要在Executor中运行的程序
  • ResourceManager收到请求后,在集群中选择一个NodeManager,为该应用程序分配第一个Container,要求它在这个Container中启动应用程序的ApplicationMaster,其中ApplicationMaster中进行SparkContext的初始化
  • ApplicationMaster向ResourceManager注册,这样用户可以直接通过ResourceManage查看应用程序的运行状态,然后它将采用轮询的方式通过RPC协议为各个任务申请资源,并监控它们的运行状态直到运行结束
  • 一旦ApplicationMaster申请到资源(也就是Container)后,便于对应的NodeManager通信,要求它在获得的Container中开始向SparkContext注册并申请执行Task任务
  • SparkContext分配给Container的Task开始执行,并向Driver汇报运行的状态和进度,让Client随时掌握各个任务的运行状态,从而可以在任务失败时重启任务
  • 应用程序运行完成后,ApplicationMaster向ResourceManager申请注销并关闭自己

Mesos模式

Mesos是Apache下的开源分布式资源管理框架,它被称为是分布式系统的内核。Mesos最初是由加州大学伯克利分校的AMPLab开发的,后在Twitter得到广泛使用。Apache Mesos是一个通用的集群管理器,起源于 Google 的数据中心资源管理系统Borg。

Mesos模式接触较少,这里不作为展开。

Kubernetes模式(K8S)

Kubernetes调度器目前是实验性的。在未来的版本中,可能会出现配置,容器图像和入口点的行为变化。 (Spark2.3.0)

Kubernetes模式接触较少,这里不作为展开。