对于某些工作负载,可以通过在内存中缓存数据或打开一些实验选项来提高性能。
在内存中缓存数据
Spark SQL可以通过调用spark.catalog.cacheTable("tableName")或者使用内存中的列式格式来缓存表dataFrame.cache()。然后,Spark SQL将仅扫描所需的列,并自动调整压缩以最小化内存使用和GC压力。我们可以调用spark.catalog.uncacheTable("tableName")从内存中删除表。
可以使用SparkSession SQL setConf上的方法或通过SET key=value使用SQL运行命令来完成内存中缓存的配置。
属性名称 | 默认 | 含义 |
spark.sql.inMemoryColumnarStorage.compressed | true | 设置为true时,Spark SQL将根据数据统计信息自动为每列选择压缩编解码器 |
spark.sql.inMemoryColumnarStorage.batchSize | 10000 | 控制柱状缓存的批次大小。较大的批处理大小可以提高内存利用率和压缩比,但在缓存数据时存在OOM风险。 |
其他配置选项
以下选项也可用于调整查询执行的性能。由于更多优化会自动执行,因此在将来的版本中可能会启用这些选项,但至少2.3.0版本还在使用。一起来看看吧:
属性名称 | 默认 | 含义 |
spark.sql.files.maxPartitionBytes | 134217728(128MB) | 读取文件时打包到单个分区的最大字节数。 |
spark.sql.files.openCostInBytes | 4194304(4MB) | 可以在同一时间扫描通过字节数测量大的打开文件的估计成本。将多个文件放入分区时使用。过度估计会更好,那么带有小文件的分区将比具有更多大文件的分区(首先安排的分区)更快。 |
spark.sql.broadcastTimeout | 300 | 广播连接中广播等待时间的超时(以秒为单位) |
spark.sql.autoBroadcastJoinThreshold | 10485760(10MB) | 配置在执行连接时将广播到所有工作节点的表最大值(以字节为单位)。通过将此值设置为-1,可以禁用广播。注意,目前只有ANALYZE TABLE<tableName> COMPUTE STATISTICS noscan运行该命令的Hive Metastore表支持统计信息。 |
spark.sql.shuffle.partitions | 200 | 配置在为连接或聚合洗牌数据时要使用的分区数。 |
SQL查询的广播提示
当与其他表或视图联合时,BROADCAS会提示引导Spark广播每个指定的表。当Spark确定连接方式时,广播散列连接(即BHJ)是首选,即使统计数据高于配置spark.sql.autoBroadcastJoinThreashold。指定连接的两端时,Spark会广播具有较低统计信息的那一方。注意Spark并不保证始终选择BHJ,因为并非所有情况(例如:全外连接)都支持BHJ。当选择广播嵌套循环连接时,我们仍尊重引导。
import static org.apache.spark.sql.functions.broadcast;
broadcast(spark.table("src")).join(spark.table("records"), "key").show();