Spark SQL----Performance Tuning性能调优


对于某些工作负载,可以通过在内存中缓存数据或打开一些实验性选项来提高性能。

一、在内存中缓存数据

Spark SQL可以通过调用spark.catalog.cacheTable(“tableName”)或dataFrame.cache()来使用内存中的列格式来缓存表。然后Spark SQL将只扫描所需的列,并自动调整压缩以最小化内存使用和GC压力。你可以调用spark.catalog.uncacheTable(“tableName”)或dataFrame.unpersist()从内存中删除表。内存缓存的配置可以使用SparkSession上的setConf方法或使用SQL运行SET key=value命令来完成。

Property NameDefaultMeaningSince Version
spark.sql.inMemoryColumnarStorage.compressedtrue当设置为true时,Spark SQL将根据统计数据自动为每列选择一个压缩编解码器。1.0.1
spark.sql.inMemoryColumnarStorage.batchSize10000控制列式缓存的批大小。较大的批处理大小可以提高内存利用率和压缩,但在缓存数据时可能会有OOM的风险。1.1.1

二、其他配置选项

还可以使用以下选项来调优查询执行的性能。在未来的版本中,这些选项可能会被弃用,因为会自动执行更多的优化。

Property NameDefaultMeaningSince Version
spark.sql.files.maxPartitionBytes134217728 (128 MB)读取文件时装入单个分区的最大字节数。此配置仅在使用基于文件的源(如Parquet、JSON和ORC)时有效。2.0.0
spark.sql.files.openCostInBytes4194304 (4 MB)打开文件的估计成本,用同一时间内可以扫描的字节数来衡量。这在将多个文件放入分区时使用。最好是高估(over-estimate),这样具有小文件的分区将比具有大文件的分区快(大文件首先被调度)。此配置仅在使用基于文件的源(如Parquet、JSON和ORC)时有效。2.0.0
spark.sql.files.minPartitionNumDefault Parallelism建议的(不保证的)最小分割文件分区数。如果没有设置,默认值为spark.sql.leafNodeDefaultParallelism。此配置仅在使用基于文件的源(如Parquet、JSON和ORC)时有效。3.1.0
spark.sql.files.maxPartitionNumNone建议的(不保证的)最大分割文件分区数。如果设置了这个值,那么当初始分区数超过这个值时,Spark将重新调整每个分区,使分区数接近这个值。此配置仅在使用基于文件的源(如Parquet、JSON和ORC)时有效。3.5.0
spark.sql.broadcastTimeout300broadcast joins中的广播等待时间超时值(以秒为单位)1.3.0
spark.sql.autoBroadcastJoinThreshold10485760 (10 MB)配置表的最大大小(以字节为单位),该表将在执行join时广播到所有工作节点。通过将此值设置为-1,可以禁用广播。请注意,目前统计数据只支持Hive Metastore表,其中命令ANALYZE TABLE <tableName> COMPUTE STATISTICS noscan已经运行。1.1.0
spark.sql.shuffle.partitions200配置为join或聚合shuffle数据时使用的分区数量。1.1.0
spark.sql.sources.parallelPartitionDiscovery.threshold32配置阈值以启用job输入路径的并行列表。如果输入路径数大于此阈值,Spark将使用Spark分布式job列出文件。否则,它将退回到sequential listing。此配置仅在使用基于文件的数据源(如Parquet、ORC和JSON)时有效。1.5.0
spark.sql.sources.parallelPartitionDiscovery.parallelism10000为job输入路径配置最大listing并行度。如果输入路径的数量大于此值,则将减少使用此值。此配置仅在使用基于文件的数据源(如Parquet、ORC和JSON)时有效。2.1.1

三、SQL查询的连接策略提示(join strategy hints)

join策略提示,即BROADCAST、MERGE、SHUFFLE_HASH和SHUFFLE_REPLICATE_NL,指示Spark在将每个指定关系与另一个关系join时,对它们使用提示的策略。例如,当对表“t1”使用BROADCAST提示时,即使统计数据建议的表“t1”的大小高于配置 spark.sql.autoBroadcastJoinThreshold,Spark也会优先考虑以“t1”为构建端的broadcast join(广播hash join或广播nested loop join,具体取决于是否存在任何equi-join键)。
当在join的两侧指定不同的join策略提示时,Spark会将使用如下优先级:BROADCAST提示优先于MERGE提示,MERGE提示优先于SHUFFLE_HASH提示,SHUFFLE_HASH提示优先于SHUFFLE_REPLICATE_NL提示。当使用BROADCAST提示或SHUFFLE_HASH提示指定两侧时,Spark将根据join类型和relations的大小选择构建侧。
请注意,不能保证Spark会选择提示中指定的join策略,因为特定的策略可能不支持所有join类型。

spark.table("src").join(spark.table("records").hint("broadcast"), "key").show()

要了解更多细节,请参考Join Hints的文档。

四、SQL查询的合并提示(Coalesce hints)

Coalesce提示允许Spark SQL用户控制输出文件的数量,就像在Dataset API中的coalesce、repartition 和repartitionByRange 一样,它们可以用于性能调优和减少输出文件的数量。“COALESCE”提示只有一个分区号作为参数。“REPARTITION”提示有分区号、列或两者都有/都没有作为参数。“REPARTITION_BY_RANGE”提示必须有列名,分区号是可选的。“REBALANCE”提示有一个初始分区号、列,或者两者都有/都没有作为参数。

SELECT /*+ COALESCE(3) */ * FROM t;
SELECT /*+ REPARTITION(3) */ * FROM t;
SELECT /*+ REPARTITION(c) */ * FROM t;
SELECT /*+ REPARTITION(3, c) */ * FROM t;
SELECT /*+ REPARTITION */ * FROM t;
SELECT /*+ REPARTITION_BY_RANGE(c) */ * FROM t;
SELECT /*+ REPARTITION_BY_RANGE(3, c) */ * FROM t;
SELECT /*+ REBALANCE */ * FROM t;
SELECT /*+ REBALANCE(3) */ * FROM t;
SELECT /*+ REBALANCE(c) */ * FROM t;
SELECT /*+ REBALANCE(3, c) */ * FROM t;

要了解更多细节,请参考Partitioning Hints文档。

五、自适应查询执行Adaptive Query Execution(AQE)

自适应查询执行(AQE)是Spark SQL中的一种优化技术,它利用运行时统计信息来选择最有效的查询执行计划,自Apache Spark 3.2.0以来默认启用。Spark SQL可以通过spark.sql.adaptive.enabled作为一个伞形配置来打开和关闭AQE。从Spark 3.0开始,AQE中有三个主要特性:合并shuffle后分区,将sort-merge join转换为broadcast join,以及skew join优化。

5.1 合并Shuffle后分区

当spark.sql.adaptive.enabled和spark.sql.adaptive.coalescePartitions.enabled配置都为true时,该特性根据映射输出统计数据合并shuffle后分区。这个特性简化了运行查询时shuffle分区数的调优。你不需要为你的数据集设置合适的shuffle分区数。一旦你通过 spark.sql.adaptive.coalescePartitions.initialPartitionNum配置设置了足够大的初始shuffle分区数,Spark就可以在运行时选择合适的shuffle分区数。

Property NameDefaultMeaningSince Version
spark.sql.adaptive.coalescePartitions.enabledtrue当为true且spark.sql.adaptive.enabled为true时,Spark将根据目标大小(由spark.sql.adaptive.advisoryPartitionSizeInBytes指定)合并连续的shuffle分区,以避免过多的小任务。3.0.0
spark.sql.adaptive.coalescePartitions.parallelismFirsttrue当为true时,Spark在合并连续shuffle分区时忽略spark.sql.adaptive.advisoryPartitionSizeInBytes(默认64MB)指定的目标大小,而只考虑spark.sql.adaptive.coalescePartitions.minPartitionSize(默认1MB)指定的最小分区大小,以最大化并行性。这是为了在启用自适应查询执行时避免性能退化。建议将此配置设置为false,并遵循spark.sql.adaptive.advisoryPartitionSizeInBytes指定的目标大小。3.2.0
spark.sql.adaptive.coalescePartitions.minPartitionSize1MB合并后shuffle分区的最小大小。它的值最多可以是spark.sql.adaptive.advisoryPartitionSizeInBytes的20%。当在分区合并期间忽略目标大小时,这是很有用的,这是默认情况。3.2.0
spark.sql.adaptive.coalescePartitions.initialPartitionNum(none)合并前shuffle分区的初始数目。如果没有设置,它等于spark.sql.shuffle.partitions。此配置仅在spark.sql.adaptive.enabled和spark.sql.adaptive.coalescePartitions.enabled同时启用时有效。3.0.0
spark.sql.adaptive.advisoryPartitionSizeInBytes64 MB自适应优化期间shuffle分区的建议大小(当spark.sql.adaptive.enabled为true时)。当Spark合并小shuffle分区或拆分倾斜shuffle分区时生效。3.0.0

5.2 分开倾斜(skew)的shuffle分区

Property NameDefaultMeaningSince Version
spark.sql.adaptive.optimizeSkewsInRebalancePartitions.enabledtrue当为true且spark.sql.adaptive.enabled为true时,Spark将优化RebalancePartitions中的倾斜shuffle分区,并根据目标大小(由spark.sql.adaptive.advisoryPartitionSizeInBytes指定)将其拆分为更小的分区,以避免数据倾斜。3.2.0
spark.sql.adaptive.rebalancePartitionsSmallPartitionFactor0.2如果分区的大小小于这个因子乘以spark.sql.adaptive.advisoryPartitionSizeInBytes,则分区将在拆分期间合并。3.3.0

5.3 将sort-merge join转换为broadcast join

当任何join端的运行时统计数据小于自适应broadcast hash join阈值时,AQE将sort-merge join转换为broadcast hash join。这并不像一开始就计划broadcast hash join那么有效,但它比继续进行sort-merge join要好,因为我们可以保存join两端的排序,并在本地读取shuffle文件以节省网络流量(如果spark.sql.adaptive.localShuffleReader.enabled为true)。

Property NameDefaultMeaningSince Version
spark.sql.adaptive.autoBroadcastJoinThreshold(none)配置表的最大大小(以字节为单位),该表将在执行join时广播到所有工作节点。通过将此值设置为-1,可以禁用广播。默认值与spark.sql.autoBroadcastJoinThreshold相同。注意,此配置仅在自适应框架中使用。3.2.0
spark.sql.adaptive.localShuffleReader.enabledtrue当为true且spark.sql.adaptive.enabled为true时,Spark会在不需要shuffle分区时(例如,将sort-merge join转换为broadcast-hash join之后)尝试使用本地shuffle reader读取shuffle数据。3.0.0

5.4 将sort-merge join转换为shuffled hash join

当所有shuffle后分区小于阈值时,AQE将sort-merge join转换为shuffled hash join,最大阈值可以查看配置spark.sql.adaptive.maxShuffledHashJoinLocalMapThreshold。

Property NameDefaultMeaningSince Version
spark.sql.adaptive.maxShuffledHashJoinLocalMapThreshold0配置可允许构建本地hash map的每个分区的最大字节大小。如果此值不小于spark.sql.adaptive.advisoryPartitionSizeInBytes且所有分区大小不大于此配置,则无论spark.sql.join.preferSortMergeJoin的值如何,join选择都倾向于使用shuffled hash join而不是sort merge join。3.2.0

5.5 Skew Join优化

数据倾斜会严重降低join查询的性能。该特性通过将倾斜的任务拆分(如果需要还可以复制)成大小大致相等的任务,动态地处理sort-merge join中的倾斜。当同时启用spark.sql.adaptive.enabled和 spark.sql.adaptive.skewJoin.enabled配置时生效。

Property NameDefaultMeaningSince Version
spark.sql.adaptive.skewJoin.enabledtrue当为true并且spark.sql.adaptive.enabled为true时,Spark通过拆分(如果需要的话还可以复制)倾斜分区来动态处理sort-merge join中的倾斜。3.0.0
spark.sql.adaptive.skewJoin.skewedPartitionFactor5.0如果分区的大小大于该因子乘以中位数分区大小,并且大于spark.sql.adaptive.skewJoin.skewedPartitionThresholdInBytes,则认为分区是倾斜的。3.0.0
spark.sql.adaptive.skewJoin.skewedPartitionThresholdInBytes256MB如果分区的字节大小大于这个阈值,并且大于spark.sql.adaptive.skewJoin.skewedPartitionFactor乘以中位数分区大小,则认为分区是倾斜的。理想情况下,这个配置应该设置得比spark.sql.adaptive.advisoryPartitionSizeInBytes大。3.0.0
spark.sql.adaptive.forceOptimizeSkewedJoinfalse当为true时,强制启用OptimizeSkewedJoin,这是一个自适应规则,用于优化倾斜join以避免straggler任务,即使它引入了额外的shuffle。3.3.0

5.6 杂项

Property NameDefaultMeaningSince Version
spark.sql.adaptive.optimizer.excludedRules(none)配置要在自适应优化器中禁用的规则列表,其中规则由其规则名称指定,并用逗号分隔。优化器将记录那些确实被排除在外的规则。3.1.0
spark.sql.adaptive.customCostEvaluatorClass(none)用于自适应执行的自定义cost evaluator类。如果没有设置,Spark将默认使用自己的SimpleCostEvaluator。3.2.0
  • 30
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值