本文仅涉及基础代码等设置调优,更深入的还请大家指出~~
1.RDD调配
对象 | 优化手段 |
RDD、DF、DS | 对于同一数据源只创建一次,尽量多次使用 |
错误示范:
val newRDD1 = spark.read.csc("/helloworld")
val newRDD2 = spark.read.csc("/helloworld")
//以上的同一RDD创建两次,资源浪费
2.持久化多次使用RDD
对象 | 优化手段 |
RDD、DF、DS | 多次调用的RDD持久化到内存 |
示范:
val demoDF = spark.read.csv("/helloWorld.csv")
demoDF.persist(StorageLevel.MEMORY_AND_DISK_SER)
demoDF.map(...)
demoDF.join(...)
demoDF.reduce(...)
//当对DF进行action操作时,spark会将整个RDD重新查询一遍,这样便十分小号资源
//persist选择将DF持久化到内存中,这样每次读取的DF就是直接从内存中拉取,
//MEMORY_AND_DISK_SER是选择在内存不足在硬盘中持久化,SER是序列化将更节省内存
3.避免shuffle
对象 | 优化手段 |
RDD、DF、DS | 尽量避免能产生shuffle的算子,如:join、reducebykey... |
描述:
产生shuffle会将所有文件中相同key的数据拉取到同一节点上,这样不单会加重节点的
运算压力,并且可能会造成数据倾斜,尽量使用map来代替
4.尽量使用高性能算子
对象 | 优化手段 |
RDD、DF、DS | 将group替换成reducebykey |
RDD、DF、DS | 使用xxxpartition这类算子,如foreachPartition代替foreach |
RDD、DF、DS | 使用filter之后,使用coalesce减少分区数,因为过滤后数据数量会减少,如果10条记录使用3个分区,即3个节点计算反而会浪费资源 |
RDD、DF、DS | 广播大变量,如果使用外部变量的时候,spark会将变量拷贝多份在网络中传输 |
RDD、DF、DS | 将group替换成reducebykey |
5.使用kryo序列化
对象 | 优化手段 |
RDD、DF、DS | spark默认是java的序列化方式,如果用到序列化,将其设置为kryo可以提高10倍性能 |
描述:
spark.config("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
6.资源调优
对象 | 优化手段 |
num-executors | Driver在向Yarn请求资源的时候,会在每个节点启动设置好的executor数量,如果没有设置的话,只会启动少量的executor。每个spark任务一般设置为30~50个executor之间,太少太多都不好 |
executor-memory | 每个executor的运行内存量,num-executors乘以executor-memory不能超过队列的总资源数,一般executor-memory设置在4g~8g之间,最好在资源的1/2以内,而不会影响机器上的其他计算 |
executor-cores | 一个executor一core只能执行一个task,同样num-executors乘以executor-cores不要超过1/2,一般设置为2~4 |
spark.default.parallelism | 该参数为spark设置stage的task数量,如果以上的资源设置充足,而此参数设置为1,则以上的资源根本没有任务去执行,一般设置为num-executors * executor-cores的2~3倍 |
描述:
./bin/spark-submit \
--master yarn-cluster \
--num-executors 100 \
--executor-memory 6G \
--executor-cores 4 \
--driver-memory 1G \
--conf spark.default.parallelism=1000
#此提交参数可以用于参考
本文参考自美团技术,感谢阅读~~