spark提交流程与调度流程

1、Driver向master注册任务,申请计算资源
2、master筛选出资源的worker
3、master通知worker启动executor
4、executor向Driver反向注册,申请计算任务
5、Driver工作:

1、运行main方法
2、创建SparkContext对象,SparkContext对象中创建了两个非常重要对象:DAGScheduler、TaskScheduler
3、根据算子先后顺序,生成DAG有向无环图
4、DAGScheduler拿到DAG有向无环图之后,会根据宽依赖切分stage,stage中存在很多分区,每一个对应一个task,最终会将每个stage中的所有的task进行封装
封装成taskset,然后将taskset交给底层的任务调度器调度执行

5、TaskScheduler拿到taskset之后,会根据stage的依赖关系,遍历taskset,将taskset中的每一个task取出来提交到executor中执行
6、所有的task执行完成之后,任务也就执行完成,Driver向master注销自己,释放资源

手画原理图:

spark挂用户执行 spark执行计划_sql

spark优化:

1.提高并行度 设置分区数的方式

如果我们将分区数设置为50个,那每一个task处理的数据是0.2G,同一时间,50个task都可以运行. 然后整个运行效率就有所提升. 在项目中分区数一般设置为CPU核数的2-3倍
设置分区的方式:
对于sparkcore: 在代码中设置.config(“spark.default.parallelism”,450)
通过repartition算子进行重分区
对于sparksql: 在代码中设置.config(“spark.sql.shuffle.partitions”,450) sparksql参数
repartition,coalese

2.增加资源

–executor-memory
–executor-cores
–num-executor

3.序列化 项目种一般采用Kryo序列化
4.本地化等待时间

场景:比如spark任务有2个stage,第一个stage运行完成之后有数据,第二个stage需要第一个stage的数据
如果HDFS的block块在node01上面,spark任务在读取HDFS文件进行处理的时候,默认将task分配node01,但是如果node01没有资源了,这个时候spark有一个等待时间spark.locality.wait,如果超过等待时间,那么spark就会在另外worker上启动task,然后从node01拉取数据进行计算

5.内存比例调优

–executor-memory 1G
内存会分为执行与存储的内存区域,用户自定义内存区域和spark保留区
spark2.0以前,执行区和存储区是固定的,如果在执行任务期间,执行区空间不足,而存储空间有剩余的时候,它并不会占用存储的空间
spark2.0以后,执行与存储区是可以动态调整,就是说如果执行区空间不足,而存储区有剩余,那么这时候,spark就会将存储区剩余空间给执行区使用.同样,如果存储区空间不足,而执行区剩余,那么spark会将执行区空闲内存给存储区使用

注意:
a.如果在任务运行前期,执行空间不足,而存储区有剩余的时候,执行区会占用存储空间,但是如果在任务后期,发现存储区空间不足,这时候不会驱逐执行区占用的空间
b.如果在任务运行前期,执行区有剩余,存储区不足,存储区会占用执行区的空间,但是如果在任务后期,发现执行区空间也不足,会驱逐存储占用的空间,将部分数据保存在磁盘.因为执行去的数据更重要
内存参数调整:
spark.memory.fraction=“0.6” 指定spark执行与存储的内存比例
sparrk.memory.storageFraction=“0.5” 指定spark存储的内存比例
如果webui界面看到GC时间特别长,证明存储对象的内存空间过小,这时候需要增大内存.增大内存有两种方式:一是直接将executor-memory设置大一点,二是将执行与存储的内存比例调小

6.广播变量

spark.sparkcontext.broadcast(广播数据)
spark.sql.autoBroadcastJoinThreshold 要广播出去的小表的限制
在工作中一般需要通过spark.sql(“cache table 表”)将表缓存之后才能正常广播出去

7.推测机制
8.代码层调优:
8.1数据倾斜 另外再写
8.2采用高性能算子:

reduceByKey代替groupByKey
mapPartition代替map
foreachPartition代替foreach

为什么选用spark, 而不是mapreduce/Hadoop?

1、mapreduce中间结果放在磁盘,spark中间结果首先放在内存,内存不够的时候才会放入磁盘
2、mapreduce的task是一个个进程,进程的创建销毁代价比较大。spark的task是一个个的线程

执行引擎为什么选用hiveonspark?

1、hivesql底层默认是mapreduce,sparksql底层默认是sparkcore
2、hivesql中间结果是保存在HDFS,sparksql中间结果是保存在内存或者本地磁盘
3、hivesql是进程级别,sparksql是线程级别
4、sparksql有catalyst优化器,hivesql没有
综上所述, spark引擎性能更好

hiveonspark的具体选用操作:

1、开启HIve支持: enableHiveSupport
2、设置metastore地址: config(“hive.metastore.uris”,"…") //hive.metastore.uris设置的值必须与hive-stie.xml中设置的值一样
3、设置warehouse的路径: confg(“spark.sql.warehouse.dir”,"…")
4、读取hive表的数据: spark.sql(“select * from 库.表”)
5.写入用: df.write.saveAsTable()