1、执行计划(过往记忆https://www.iteblog.com/archives/2562.html)
df.explain(true)//显示逻辑计划和物理计划,不加true只显示物理计划
2、逻辑计划优化方法:
谓词下推,列裁剪,常量替换,常量累加
3、优化方法
数据源方面:
1、hive 使用parquet格式,不要用textfile。列式存储便于查询引擎做谓词下推、更优的压缩算法(不同列可以采取不同的压缩算法)减少IO,块遍历等优化方法。
2、Kafka根据key的hash值分区,OGG到Kafka 表名作为key,因此不同大小的表可以更改表名,均衡分到不同partition。
sparkSQL程序方面(spark优化):
1、多次用到的表,做cache。默认进行压缩。
spark.sql.inMemoryColumnarStorage.compressed //默认为true,为每个列选择压缩方式 spark.sql.inMemoryColumnarStorage.batchSize //默认为10000 byte 控制列缓存的批量大小。批次大有助于改善内存使用和压缩,但是缓存数据会有OOM的风险
2、小于10M的表会自动broadcast,走broadcast join,调高广播表的大小,使其走broadcast join ,但是太大有可能driver端OOM,-1为禁止自动广播。
当使用的外部变量较大时,也可把外部变量作为广播变量进行广播。
spark.sql.autoBroadcastJoinThreshold //默认10485760 (10 MB)
val listBrodcast = spark.sparkContext.broadcast(list)
3、sparkSQL shuffle read partition默认为200,提高可解决部分数据倾斜问题。
spark.sql.shuffle.partitions //默认200
4、读不可分割的文件,一个文件一个partition,若小文件过多,影响效率,设置多个文件写入一个分区
spark.sql.files.openCostInBytes //默认4194304 (4 MB),打开一个文件的时间可读取4MB数据,因此小于4M的文件读入一个分区(待验证) spark.sql.files.maxPartitionBytes //默认134217728 (128 MB),文件传入一个分区里的最大字节数
5、使用高效的算子
1、reduceByKey/aggregateByKey代替groupByKey//前者partition内部会进行预聚合,后者不进行预聚合直接全局shuffle 2、mapPartitions代替map,foreachpartitions 代替foreach//前者会一次性读取整个partition的数据进行处理,比如建立数据库连接在foreachpartitions中,不要在foreach 3、filter之后coallease
6、修改序列化器为kryo,并注册序列化类
conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
conf.registerKryoClasses(Array(classOf[MyClass1], classOf[MyClass2])
7、join方式(https://www.cnblogs.com/suanec/p/7560399.html)