1. spark-submit介绍
spark-submit
脚本通常位于/usr/local/spark/bin
目录下,可以用which spark-submit
来查看它所在的位置,spark-submit
用来启动集群中的应用,它使用统一的提交接口支持各种类型的集群服务器。为了将应用发布到集群中,通常会将应用打成.jar
包,在运行spark-submit
时将jar
包当做参数提交。
2. spark-submit参数
spark-submit
脚本使用时有很多启动参数,启动参数说明如下:
Parameters | Description | Demo |
---|---|---|
–master | 集群master的URL,可以是spark://host:port, mesos://host:port, yarn, yarn-cluster,yarn-client, local | --master yarn |
–class | 主类的名称,包括完整的包路径。 | --class com.ltc.test /home/ltc/spark-test.jar |
–conf | 任意的Spark配置属性,格式key=value,如果值包含空格,可以加引号“key=value”。 | --conf spark.cores.max=2 |
–num-executors | 该参数用于设置Spark作业总共要用多少个Executor进程来执行。Driver在向YARN集群管理器申请资源时,YARN集群管理器会尽可能按照你的设置来在集群的各个工作节点上,启动相应数量的Executor进程。 | --num-executors 100 |
–executor-memory | 该参数用于设置每个Executor进程的内存。Executor内存的大小,很多时候直接决定了Spark作业的性能,而且跟常见的JVM OOM异常,也有直接的关联。建议每个Executor进程的内存设置4G~8G较为合适。看看资源队列的最大内存限制是多少,num-executors乘以executor-memory,就代表了你的Spark作业申请到的总内存量 | --executor-memory 4G |
–executor-cores | 该参数用于设置每个Executor进程的CPU core数量。这个参数决定了每个Executor进程并行执行task线程的能力。因为每个CPU core同一时间只能执行一个task线程,因此每个Executor进程的CPU core数量越多,越能够快速地执行完分配给自己的所有task线程。Executor的CPU core数量设置为2~4个较为合适。 | --executor-cores 4 |
–driver-memory | Driver 程序运行时需要的内存, 默认为512M。 | --driver-memory 1G |
–name | 应用名称 | --name application |
–conf spark.default.parallelism | 该参数用于设置每个stage的默认task数量。这个参数极为重要,如果不设置可能会直接影响你的Spark作业性能。建议:Spark作业的默认task数量多一点。不设置这个参数是个错误,默认情况下,Spark根据底层HDFS的block数量来设置task的数量,默认是一个HDFS block对应一个task。通常来说,Spark默认设置的数量是偏少的(比如就几十个task),如果task数量偏少的话,就会导致前面设置的Executor参数作用不大。无论Executor进程有多少个,内存和CPU有多大,但是task只有1个或者10个,那么90%的Executor进程可能根本就没有task执行,会白白浪费了资源!Spark官网建议的设置原则是,设置该参数为num-executors * executor-cores的2~3倍较为合适,比如Executor的总CPU core数量为300个,那么设置1000个task是可以的,此时可以充分地利用Spark集群的资源。 | --conf spark.default.parallelism=100 |
–conf spark.storage.memoryFraction | 该参数用于设置RDD持久化数据在Executor内存中能占的比例,默认是0.6。也就是说,默认Executor 60%的内存,可以用来保存持久化的RDD数据。根据你选择的不同的持久化策略,如果内存不够时,可能数据就不会持久化,或者数据会写入磁盘。建议:如果Spark作业中,有较多的RDD持久化操作,该参数的值可以适当提高一些,保证持久化的数据能够容纳在内存中。避免内存不够缓存所有的数据,导致数据只能写入磁盘中,降低了性能。但是如果Spark作业中的shuffle类操作比较多,而持久化操作比较少,那么这个参数的值适当降低一些比较合适。此外,如果发现作业由于频繁的gc导致运行缓慢(通过spark web ui可以观察到作业的gc耗时),意味着task执行用户代码的内存不够用,那么同样建议调低这个参数的值。 | --conf spark.storage.memoryFraction=0.5 |
–conf spark.shuffle.memoryFraction | 该参数用于设置shuffle过程中一个task拉取到上个stage的task的输出后,进行聚合操作时能够使用的Executor内存的比例,默认是0.2。也就是说,Executor默认只有20%的内存用来进行该操作。shuffle操作在进行聚合时,如果发现使用的内存超出了这个20%的限制,那么多余的数据就会溢写到磁盘文件中去,此时就会极大地降低性能。建议:如果Spark作业中的RDD持久化操作较少,shuffle操作较多时,建议降低持久化操作的内存占比,提高shuffle操作的内存占比比例,避免shuffle过程中数据过多时内存不够用,必须溢写到磁盘上,降低了性能。此外,如果发现作业由于频繁的gc导致运行缓慢,意味着task执行用户代码的内存不够用,那么同样建议调低这个参数的值。 | --conf spark.shuffle.memoryFraction=0.3 |